home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr48 / ned100.zip / NEWEDIT.PAS < prev    next >
Pascal/Delphi Source File  |  1993-04-08  |  160KB  |  6,136 lines

  1. { FILE:  newedit.pas }
  2.  
  3.  
  4.  
  5. unit NewEdit;
  6.  
  7.  
  8.  
  9. { ******************************************************************** }
  10. {                                                                      }
  11. { NOTICE:  The following code was written by Borland International.    }
  12. {          The code is for use by TP6.0 users.  Keep the copyright     }
  13. {          notice intact!                                              }
  14. {                                                                      }
  15. {          Turbo Pascal 6.0                                            }
  16. {          Turbo Vision Demo                                           }
  17. {          Copyright (c) 1990 by Borland International                 }
  18. {                                                                      }
  19. {          I have taken the liberty of prettying up the source.        }
  20. {          I have also taken the liberty of adding additional features.}
  21. {          Search for the following keywords and compare your original }
  22. {          editors code to any code between the Start/Stop comments    }
  23. {          for changes.                                                }
  24. {                                                                      }
  25. { Label    Description:                                                }
  26. { ------   ------------                                                }
  27. {                                                                      }
  28. { CENTER - Added a feature to center text on a line.                   }
  29. {          Centering only works to Right_Margin.                       }
  30. {                                                                      }
  31. { CTRLBK - Added new key to map to ^QH.  Does the same thing.          }
  32. {                                                                      }
  33. { HOMEND - Added feature to move cursor to top and bottom of page      }
  34. {          using the [Ctrl]-[Home] and [Ctrl]-[End] keys.              }
  35. {                                                                      }
  36. { LOAD   - Fixed bug that prevented load operations and added new      }
  37. {          stream reads to handle new TEditor objects.                 }
  38. {                                                                      }
  39. { MARK   - A place mark type feature.  Exactly the same as WordStar's  }
  40. {          ^K# and ^Q#, except that the mark is for the exact poistion }
  41. {          the cursor is at in a line, not just the start of a line.   }
  42. {                                                                      }
  43. { INDENT - Change AutoIndent from a ^O to a ^QI call.                  }
  44. {                                                                      }
  45. { INSLIN - Insert new line at cursor and maintain cursor position.     }
  46. {                                                                      }
  47. { JLINE  - A jump to line number feature.  Pressing ^JL will bring     }
  48. {          up a dialog box asking the line number to jump to.          }
  49. {                                                                      }
  50. { PRETAB - Preset tab feature.  Tabs are preset in increments of 7.    }
  51. {          The user can call up a dialog and set the tabs in any way   }
  52. {          they want.  Uses WordStar ^OI feature.  Note that a "real"  }
  53. {          tab (^I) is no longer supported.  Tabs are converted to     }
  54. {          spaces if you are inserting text, and only move the cursor  }
  55. {          to the next tab stop if you are overwriting text.           }
  56. {                                                                      }
  57. { REFDOC - Reformats a document from either the beginning or the       }
  58. {          current line the cursor is on.                              }
  59. {                                                                      }
  60. { REFORM - Reformats a paragraph to the Right_Margin setting.          }
  61. {          This feature works regardless if wordwrap is active,        }
  62. {          as a standalone ^B call.                                    }
  63. {                                                                      }
  64. { RMSET  - User can set the Right_Margin by pressing ^OR.  A dialog    }
  65. {          box comes up asking you for the Right_Margin you want.      }
  66. {          The dialog box has the current Right_Margin displayed in    }
  67. {          it.  There is only one dialog button "cmOK."  Selecting     }
  68. {          this button, or aborting, will maintain the current margin. }
  69. {          Default Right_Margin is 76.  Valid entries are >10 or < 256.}
  70. {                                                                      }
  71. { SAVE   - Add new save options.  Keep F2 as the default cmSave to     }
  72. {          save file and continue editing, but tie ^KS to it also.     }
  73. {          Add ^KT to cmSaveAs to save current file to another file.   }
  74. {          Add ^KD and ^KX as cmSaveDone to do an immediate save and   }
  75. {          automatically remove the editor from the desktop.           }
  76. {                                                                      }
  77. { SCRLBG - Added a bug fix so editor doesn't consume ScrollbarChanged  }
  78. {          events.                                                     }
  79. {                                                                      }
  80. { SCRLDN - Added feature to scroll the screen up a line-at-a-time      }
  81. {          by pressing ^Z.                                             }
  82. {                                                                      }
  83. { SCRLUP - Added feature to scroll the screen down a line-at-a-time    }
  84. {          by pressing ^W.                                             }
  85. {                                                                      }
  86. { SELDEL - Disallowed editor default of arbitrarily deleting selected  }
  87. {          text when any key is pressed.  You now use the [Del] key.   }
  88. {                                                                      }
  89. { SELWRD - Added feature to select a word only by pressing ^KT.        }
  90. {                                                                      }
  91. { STATS  - Changed the appearance of the PIndicator line.              }
  92. {          It now shows "M" for modified, "I" for AutoIndent,          }
  93. {          and "W" for wordwrap.                                       }
  94. {                                                                      }
  95. { STORE  - Fixed bug that prevented store operations and added new     }
  96. {          stream writes to handle new TEditor objects.  Send thanks   }
  97. {          to Johnathan Stein CIS: 76576,470 in the form of a lollipop }
  98. {          for finding this bug.                                       }
  99. {                                                                      }
  100. { UNDO   - Added IDE ^QL undo feature.  ^U is still functional.        }
  101. {                                                                      }
  102. { WRAP   - A word wrap modification.  Allows user to toggle wordwrap   }
  103. {          on or off.  If on, wordwrap will occur when the cursor      }
  104. {          reaches +1 of the current Right_Margin setting.  Wrap works }
  105. {          as a "push the line out until cursor gets to Right_Margin"  }
  106. {          principle.  Wordwrap also supports the AutoIndent feature.  }
  107. {                                                                      }
  108. { Al Andersen - 02/29/92.                                              }
  109. {                                                                      }
  110. { ******************************************************************** }
  111.  
  112.  
  113. {$F+,I-,O+,S-,V-,X+,D-}
  114.  
  115.  
  116.  
  117. interface
  118.  
  119. uses Drivers,
  120.      Objects,
  121.      Views;
  122.  
  123.  
  124.  
  125. CONST { Command constants for saving files and finding text. }
  126.  
  127.   cmSave        = 80;
  128.   cmSaveAs      = 81;
  129.   cmFind        = 82;
  130.   cmReplace     = 83;
  131.   cmSearchAgain = 84;
  132.  
  133.   { SAVE - Start. }
  134.  
  135.   cmSaveDone    = 85;
  136.  
  137.   { SAVE - Stop.  }
  138.  
  139.  
  140.  
  141. CONST { New editor commands that user may want to put into a menu. }
  142.  
  143.   { CENTER - Start. }
  144.   { HOMEND - Start. }
  145.   { INSLIN - Start. }
  146.   { JLINE  - Start. }
  147.   { MARK   - Start. }
  148.   { PRETAB - Start. }
  149.   { REFDOC - Start. }
  150.   { REFORM - Start. }
  151.   { RMSET  - Start. }
  152.   { SCRLDN - Start. }
  153.   { SCRLDN - Start. }
  154.   { SELWRD - Start. }
  155.   { WRAP   - Start. }
  156.  
  157.   cmCenterText  = 200;
  158.   cmEndPage     = 201;
  159.   cmHomePage    = 202;
  160.   cmIndentMode  = 203;
  161.   cmInsertLine  = 204;
  162.   cmJumpLine    = 205;
  163.   cmJumpMark0   = 206;
  164.   cmJumpMark1   = 207;
  165.   cmJumpMark2   = 208;
  166.   cmJumpMark3   = 209;
  167.   cmJumpMark4   = 210;
  168.   cmJumpMark5   = 211;
  169.   cmJumpMark6   = 212;
  170.   cmJumpMark7   = 213;
  171.   cmJumpMark8   = 214;
  172.   cmJumpMark9   = 215;
  173.   cmReformDoc   = 216;
  174.   cmReformPara  = 217;
  175.   cmRightMargin = 218;
  176.   cmScrollDown  = 219;
  177.   cmScrollUp    = 220;
  178.   cmSelectWord  = 221;
  179.   cmSetMark0    = 222;
  180.   cmSetMark1    = 223;
  181.   cmSetMark2    = 224;
  182.   cmSetMark3    = 225;
  183.   cmSetMark4    = 226;
  184.   cmSetMark5    = 227;
  185.   cmSetMark6    = 228;
  186.   cmSetMark7    = 229;
  187.   cmSetMark8    = 230;
  188.   cmSetMark9    = 231;
  189.   cmSetTabs     = 232;
  190.   cmTabKey      = 233;
  191.   cmWordWrap    = 234;
  192.  
  193.  
  194.   { WRAP   - Stop. }
  195.   { SELWRD - Stop. }
  196.   { SCRLUP - Stop. }
  197.   { SCRLDN - Stop. }
  198.   { RMSET  - Stop. }
  199.   { REFORM - Stop. }
  200.   { REFDOC - Stop. }
  201.   { PRETAB - Stop. }
  202.   { MARK   - Stop. }
  203.   { JLINE  - Stop. }
  204.   { INSLIN - Stop. }
  205.   { HOMEND - Stop. }
  206.   { CENTER - Stop. }
  207.  
  208.  
  209.  
  210. CONST { Command constants for cursor movement and modifying text. }
  211.  
  212.   cmCharLeft      = 500;
  213.   cmCharRight     = 501;
  214.   cmWordLeft      = 502;
  215.   cmWordRight     = 503;
  216.   cmLineStart     = 504;
  217.   cmLineEnd       = 505;
  218.   cmLineUp        = 506;
  219.   cmLineDown      = 507;
  220.   cmPageUp        = 508;
  221.   cmPageDown      = 509;
  222.   cmTextStart     = 510;
  223.   cmTextEnd       = 511;
  224.   cmNewLine       = 512;
  225.   cmBackSpace     = 513;
  226.   cmDelChar       = 514;
  227.   cmDelWord       = 515;
  228.   cmDelStart      = 516;
  229.   cmDelEnd        = 517;
  230.   cmDelLine       = 518;
  231.   cmInsMode       = 519;
  232.   cmStartSelect   = 520;
  233.   cmHideSelect    = 521;
  234.   cmUpdateTitle   = 523;
  235.  
  236.   { STATS - Start. }
  237.  
  238.   cmBludgeonStats = 524;
  239.  
  240.   { STATS - Stop. } { Needed this for TEditWindow.HandleEvent }
  241.  
  242.  
  243.  
  244. CONST { Editor constants for dialog boxes. }
  245.  
  246.   edOutOfMemory   = 0;
  247.   edReadError     = 1;
  248.   edWriteError    = 2;
  249.   edCreateError   = 3;
  250.   edSaveModify    = 4;
  251.   edSaveUntitled  = 5;
  252.   edSaveAs        = 6;
  253.   edFind          = 7;
  254.   edSearchFailed  = 8;
  255.   edReplace       = 9;
  256.   edReplacePrompt = 10;
  257.  
  258.   { JLINE  - Start. }
  259.   { PRETAB - Start. }
  260.   { REFDOC - Start. }
  261.   { RMSET  - Start. }
  262.   { WRAP   - Start. }
  263.  
  264.   edJumpToLine         = 11;
  265.   edPasteNotPossible   = 12;
  266.   edReformatDocument   = 13;
  267.   edReformatNotAllowed = 14;
  268.   edReformNotPossible  = 15;
  269.   edReplaceNotPossible = 16;
  270.   edRightMargin        = 17;
  271.   edSetTabStops        = 18;
  272.   edWrapNotPossible    = 19;
  273.  
  274.   { WRAP   - Stop. }
  275.   { RMSET  - Stop. }
  276.   { REFDOC - Stop. }
  277.   { PRETAB - Stop. }
  278.   { JLINE  - Stop. }
  279.  
  280.  
  281.  
  282. CONST { Editor flag constants for dialog options. }
  283.  
  284.   efCaseSensitive   = $0001;
  285.   efWholeWordsOnly  = $0002;
  286.   efPromptOnReplace = $0004;
  287.   efReplaceAll      = $0008;
  288.   efDoReplace       = $0010;
  289.   efBackupFiles     = $0100;
  290.  
  291.  
  292.  
  293. CONST { Constants for object palettes. }
  294.  
  295.   CIndicator = #2#3;
  296.   CEditor    = #6#7;
  297.   CMemo      = #26#27;
  298.  
  299.  
  300.  
  301. CONST { Length constants. }
  302.  
  303.   MaxLineLength = 256;
  304.  
  305.   { PRETAB - Start. }
  306.  
  307.   Tab_Stop_Length = 74;
  308.  
  309.   { PRETAB - Stop. }
  310.  
  311.  
  312.  
  313. TYPE
  314.  
  315.   TEditorDialog = function (Dialog : Integer; Info : Pointer) : Word;
  316.  
  317.  
  318.  
  319. TYPE
  320.  
  321.   PIndicator = ^TIndicator;
  322.   TIndicator = object (TView)
  323.  
  324.     Location   : Objects.TPoint;
  325.     Modified   : Boolean;
  326.  
  327.     { STATS - Start. }
  328.  
  329.     AutoIndent   : Boolean;          { Added boolean for AutoIndent mode. }
  330.     WordWrap     : Boolean;          { Added boolean for WordWrap mode.   }
  331.  
  332.     { STATS - Stop. }
  333.  
  334.     constructor Init (var Bounds : TRect);
  335.     procedure   Draw; virtual;
  336.     function    GetPalette : Views.PPalette; virtual;
  337.     procedure   SetState (AState : Word; Enable : Boolean); virtual;
  338.  
  339.     { STATS - Start. }
  340.  
  341.     procedure   SetValue (ALocation : Objects.TPoint; IsAutoIndent : Boolean;
  342.                                                       IsModified   : Boolean;
  343.                                                       IsWordWrap   : Boolean);
  344.  
  345.     { STATS - Stop. } { Changed parameter calls to show them on TIndicator line. }
  346.  
  347.   end;
  348.  
  349.  
  350.  
  351. TYPE
  352.  
  353.   PEditBuffer = ^TEditBuffer;
  354.   TEditBuffer = array[0..65519] of Char;
  355.  
  356.  
  357.  
  358. TYPE
  359.  
  360.   PEditor = ^TEditor;
  361.   TEditor = object (TView)
  362.  
  363.     HScrollBar         : PScrollBar;
  364.     VScrollBar         : PScrollBar;
  365.     Indicator          : PIndicator;
  366.     Buffer             : PEditBuffer;
  367.     BufSize            : Word;
  368.     BufLen             : Word;
  369.     GapLen             : Word;
  370.     SelStart           : Word;
  371.     SelEnd             : Word;
  372.     CurPtr             : Word;
  373.     CurPos             : Objects.TPoint;
  374.     Delta              : Objects.TPoint;
  375.     Limit              : Objects.TPoint;
  376.     DrawLine           : Integer;
  377.     DrawPtr            : Word;
  378.     DelCount           : Word;
  379.     InsCount           : Word;
  380.     IsValid            : Boolean;
  381.     CanUndo            : Boolean;
  382.     Modified           : Boolean;
  383.     Selecting          : Boolean;
  384.     Overwrite          : Boolean;
  385.     AutoIndent         : Boolean;
  386.  
  387.     { WRAP - Start. }
  388.  
  389.     BlankLine          : Word;    { First blank line after a paragraph.      }
  390.     Word_Wrap          : Boolean; { Added boolean to toggle wordwrap on/off. }
  391.  
  392.     { WRAP - Stop. }
  393.  
  394.     { JLINE - Start. }
  395.  
  396.     Line_Number        : string [4]; { Holds line number to jump to. }
  397.  
  398.     { JLINE - Stop. }
  399.  
  400.     { RMSET - Start. }
  401.  
  402.     Right_Margin       : Integer; { Added integer to set right margin.       }
  403.  
  404.     { RMSET - Stop. }
  405.  
  406.     { PRETAB - Start. }
  407.  
  408.     Tab_Settings : String[Tab_Stop_Length]; { Added string to hold tab stops. }
  409.  
  410.     { PRETAB - Stop. }
  411.  
  412.     constructor Init (var Bounds : TRect; AHScrollBar, AVScrollBar : PScrollBar;
  413.                           AIndicator : PIndicator; ABufSize : Word);
  414.     constructor Load (var S : Objects.TStream);
  415.     destructor Done; virtual;
  416.     function   BufChar (P : Word) : Char;
  417.     function   BufPtr (P : Word) : Word;
  418.     procedure  ChangeBounds (var Bounds : TRect); virtual;
  419.     procedure  ConvertEvent (var Event : Drivers.TEvent); virtual;
  420.     function   CursorVisible : Boolean;
  421.     procedure  DeleteSelect;
  422.     procedure  DoneBuffer; virtual;
  423.     procedure  Draw; virtual;
  424.     function   GetPalette : Views.PPalette; virtual;
  425.     procedure  HandleEvent (var Event : Drivers.TEvent); virtual;
  426.     procedure  InitBuffer; virtual;
  427.     function   InsertBuffer (var P : PEditBuffer; Offset, Length : Word;
  428.                                      AllowUndo, SelectText : Boolean) : Boolean;
  429.     function   InsertFrom (Editor : PEditor) : Boolean; virtual;
  430.     function   InsertText (Text : Pointer; Length : Word; SelectText : Boolean) : Boolean;
  431.     procedure  ScrollTo (X, Y : Integer);
  432.     function   Search (FindStr : String; Opts : Word) : Boolean;
  433.     function   SetBufSize (NewSize : Word) : Boolean; virtual;
  434.     procedure  SetCmdState (Command : Word; Enable : Boolean);
  435.     procedure  SetSelect (NewStart, NewEnd : Word; CurStart : Boolean);
  436.     procedure  SetState (AState : Word; Enable : Boolean); virtual;
  437.     procedure  Store (var S : Objects.TStream);
  438.     procedure  TrackCursor (Center : Boolean);
  439.     procedure  Undo;
  440.     procedure  UpdateCommands; virtual;
  441.     function   Valid (Command : Word) : Boolean; virtual;
  442.  
  443.   private
  444.  
  445.     KeyState       : Integer;
  446.     LockCount      : Byte;
  447.     UpdateFlags    : Byte;
  448.  
  449.     { MARK - Start. }
  450.  
  451.     Place_Marker   : Array [1..10] of Word; { Inserted array to hold place markers. }
  452.     Search_Replace : Boolean; { Added boolean to test for Search and Replace insertions. }
  453.  
  454.     { MARK - Stop. }
  455.  
  456.     { CENTER - Start. }
  457.  
  458.     procedure  Center_Text (Select_Mode : Byte);
  459.  
  460.     { CENTER - Stop. } { Added procedure to center a line of text. }
  461.  
  462.     function   CharPos (P, Target : Word) : Integer;
  463.     function   CharPtr (P : Word; Target : Integer) : Word;
  464.  
  465.     { WRAP -   Start. }
  466.  
  467.     procedure  Check_For_Word_Wrap (Select_Mode : Byte; Center_Cursor : Boolean);
  468.  
  469.     { WRAP -   Stop. } { Added procedure to check for word wrap. }
  470.  
  471.     function   ClipCopy : Boolean;
  472.     procedure  ClipCut;
  473.     procedure  ClipPaste;
  474.     procedure  DeleteRange (StartPtr, EndPtr : Word; DelSelect : Boolean);
  475.     procedure  DoSearchReplace;
  476.     procedure  DoUpdate;
  477.  
  478.     { WRAP -   Start. }
  479.  
  480.     function   Do_Word_Wrap (Select_Mode : Byte; Center_Cursor : Boolean) : Boolean;
  481.  
  482.     { WRAP -   Stop. } { Added procedure to check for word wrap. }
  483.  
  484.     procedure  DrawLines (Y, Count : Integer; LinePtr : Word);
  485.     procedure  FormatLine (var DrawBuf; LinePtr : Word; Width : Integer; Colors : Word);
  486.     procedure  Find;
  487.     function   GetMousePtr (Mouse : Objects.TPoint) : Word;
  488.     function   HasSelection : Boolean;
  489.     procedure  HideSelect;
  490.  
  491.     { INSLIN - Start. }
  492.  
  493.     procedure  Insert_Line (Select_Mode : Byte);
  494.  
  495.     { INSLIN - Stop. } { Added procedure to insert line at cursor. }
  496.  
  497.     function   IsClipboard : Boolean;
  498.  
  499.     { MARK -   Start. }
  500.  
  501.     procedure  Jump_Place_Marker (Element : Byte; Select_Mode : Byte);
  502.  
  503.     { MARK -   Stop. } { Added procedure to jump to a place marker if ^Q# is pressed. }
  504.  
  505.     { JLINE -  Start }
  506.  
  507.     procedure  Jump_To_Line  (Select_Mode : Byte);
  508.  
  509.     { JLINE -  Stop. }
  510.  
  511.     function   LineEnd (P : Word) : Word;
  512.     function   LineMove (P : Word; Count : Integer) : Word;
  513.     function   LineStart (P : Word) : Word;
  514.     procedure  Lock;
  515.  
  516.     { WRAP -   Start. }
  517.  
  518.     procedure  NewLine (Select_Mode : Byte);
  519.  
  520.     { WRAP -   Stop. } { Included a new parameter. }
  521.  
  522.     function   NextChar (P : Word) : Word;
  523.     function   NextLine (P : Word) : Word;
  524.     function   NextWord (P : Word) : Word;
  525.     function   PrevChar (P : Word) : Word;
  526.     function   PrevLine (P : Word) : Word;
  527.     function   PrevWord (P : Word) : Word;
  528.  
  529.     { REFDOC - Start. }
  530.  
  531.     procedure  Reformat_Document (Select_Mode : Byte; Center_Cursor : Boolean);
  532.  
  533.     { REFDOC - Stop. } { Added procedure to allow document reformatting. }
  534.  
  535.     { REFORM - Start. }
  536.  
  537.     function   Reformat_Paragraph (Select_Mode   : Byte;
  538.                                    Center_Cursor : Boolean) : Boolean;
  539.  
  540.     { REFORM - Stop. } { Added procedure to reformat paragraphs. }
  541.  
  542.     { WRAP -   Start. }
  543.  
  544.     procedure  Remove_EOL_Spaces (Select_Mode : Byte);
  545.  
  546.     { WRAP -   Stop. }  { Added procedure to remove spaces at end of a line. }
  547.  
  548.     procedure  Replace;
  549.  
  550.     { SCRLDN - Start. }
  551.  
  552.     procedure  Scroll_Down;
  553.  
  554.     { SCRLDN - Stop. }
  555.  
  556.     { SCRLUP - Start. }
  557.  
  558.     procedure  Scroll_Up;
  559.  
  560.     { SCRLUP - Stop. }
  561.  
  562.     { SELWRD - Start. }
  563.  
  564.     procedure  Select_Word;
  565.  
  566.     { SELWRD - Stop. } { Added procedure to allow selecting a word only. }
  567.  
  568.     procedure  SetBufLen (Length : Word);
  569.     procedure  SetCurPtr (P : Word; SelectMode : Byte);
  570.  
  571.     { MARK -   Start. }
  572.  
  573.     procedure  Set_Place_Marker (Element : Byte);
  574.  
  575.     { MARK -   Stop. } { Added procedure to set a Place_Marker if ^K# is pressed. }
  576.  
  577.     { RMSET -  Start. }
  578.  
  579.     procedure  Set_Right_Margin;
  580.  
  581.     { RMSET -  Stop. } { Added procedure to set Right_Margin via a dialog box. }
  582.  
  583.     { PRETAB - Start. }
  584.  
  585.     procedure  Set_Tabs;
  586.  
  587.     { PRETAB - Stop. } { Added procedure to allow preset tabs. }
  588.  
  589.     procedure  StartSelect;
  590.  
  591.     { PRETAB - Start. }
  592.  
  593.     procedure  Tab_Key (Select_Mode : Byte);
  594.  
  595.     { PRETAB - Stop. } { Added procedure to process Tab key as spaces or movment. }
  596.  
  597.     procedure  ToggleInsMode;
  598.     procedure  Unlock;
  599.     procedure  Update (AFlags : Byte);
  600.  
  601.     { MARK -   Start. }
  602.  
  603.     procedure  Update_Place_Markers (AddCount : Word; KillCount : Word;
  604.                                      StartPtr : Word;    EndPtr : Word);
  605.  
  606.     { MARK -   Stop. } { Added procedure to update Place_Marker as we change text. }
  607.  
  608.   end;
  609.  
  610.  
  611.  
  612. TYPE
  613.  
  614.   TMemoData = record
  615.  
  616.     Length : Word;
  617.     Buffer : TEditBuffer;
  618.  
  619.   end;
  620.  
  621.  
  622.  
  623. TYPE
  624.  
  625.   PMemo = ^TMemo;
  626.   TMemo = object (TEditor)
  627.  
  628.     constructor Load (var S : Objects.TStream);
  629.     function    DataSize : Word; virtual;
  630.     procedure   GetData (var Rec); virtual;
  631.     function    GetPalette : Views.PPalette; virtual;
  632.     procedure   HandleEvent (var Event : Drivers.TEvent); virtual;
  633.     procedure   SetData (var Rec); virtual;
  634.     procedure   Store (var S : Objects.TStream);
  635.  
  636.   end;
  637.  
  638.  
  639.  
  640. TYPE
  641.  
  642.   PFileEditor = ^TFileEditor;
  643.   TFileEditor = object (TEditor)
  644.  
  645.     FileName : FNameStr;
  646.  
  647.     constructor Init (var Bounds : TRect; AHScrollBar, AVScrollBar : PScrollBar;
  648.                           AIndicator : PIndicator; AFileName : FNameStr);
  649.     constructor Load (var S : Objects.TStream);
  650.     procedure   DoneBuffer; virtual;
  651.     procedure   HandleEvent (var Event : Drivers.TEvent); virtual;
  652.     procedure   InitBuffer; virtual;
  653.     function    LoadFile : Boolean;
  654.     function    Save : Boolean;
  655.     function    SaveAs : Boolean;
  656.     function    SaveFile : Boolean;
  657.     function    SetBufSize (NewSize : Word) : Boolean; virtual;
  658.     procedure   Store (var S : Objects.TStream);
  659.     procedure   UpdateCommands; virtual;
  660.     function    Valid (Command : Word) : Boolean; virtual;
  661.  
  662.   end;
  663.  
  664.  
  665.  
  666. TYPE
  667.  
  668.   PEditWindow = ^TEditWindow;
  669.   TEditWindow = object (TWindow)
  670.  
  671.     Editor : PFileEditor;
  672.  
  673.     constructor Init (var Bounds : TRect; FileName : FNameStr; ANumber : Integer);
  674.     constructor Load (var S : Objects.TStream);
  675.     procedure   Close; virtual;
  676.     function    GetTitle (MaxSize : Integer) : Views.TTitleStr; virtual;
  677.     procedure   HandleEvent (var Event : Drivers.TEvent); virtual;
  678.     procedure   Store (var S : Objects.TStream);
  679.  
  680.   end;
  681.  
  682.  
  683.  
  684. function DefEditorDialog (Dialog : Integer; Info : Pointer) : Word;
  685.  
  686.  
  687.  
  688. CONST
  689.  
  690.   { PRETAB - Start. }
  691.   { WRAP   - Start. }
  692.  
  693.   WordChars    : set of Char = ['!'..#255];
  694.  
  695.   { WRAP   - Stop. }
  696.   { PRETAB - Stop. } { Changed set parameters to allow punctuation. }
  697.  
  698.  
  699.  
  700.   { ------------------------------------------------- }
  701.   {                                                   }
  702.   { The Allow_Reformat boolean is a programmer hook.  }
  703.   { I've placed this here to allow programmers to     }
  704.   { determine whether or not paragraph and document   }
  705.   { reformatting are allowed if Word_Wrap is not      }
  706.   { active.  Some people say don't allow, and others  }
  707.   { say allow it.  I've left it up to the programmer. }
  708.   { Set to FALSE if not allowed, or TRUE if allowed.  }
  709.   {                                                   }
  710.   { ------------------------------------------------- }
  711.  
  712.   Allow_Reformat : Boolean = True;
  713.  
  714.   EditorDialog   : TEditorDialog = DefEditorDialog;
  715.   EditorFlags    : Word = efBackupFiles + efPromptOnReplace;
  716.   FindStr        : String[80] = '';
  717.   ReplaceStr     : String[80] = '';
  718.   Clipboard      : PEditor = nil;
  719.  
  720.  
  721.  
  722. TYPE
  723.  
  724.   TFindDialogRec = record
  725.  
  726.     Find    : String[80];
  727.     Options : Word;
  728.  
  729.   end;
  730.  
  731.  
  732.  
  733.   TReplaceDialogRec = record
  734.  
  735.        Find : String[80];
  736.     Replace : String[80];
  737.     Options : Word;
  738.  
  739.   end;
  740.  
  741.  
  742.  
  743.   { RMSET - Start. }
  744.  
  745.   TRightMarginRec = record
  746.  
  747.     Margin_Position : String[3];
  748.  
  749.   end;
  750.  
  751.   { RMSET - Stop. } { Record required by Right_Margin_Dialog. }
  752.  
  753.  
  754.  
  755.   { PRETAB - Start. }
  756.  
  757.   TTabStopRec = record
  758.  
  759.     Tab_String : String [Tab_Stop_Length];
  760.  
  761.   end;
  762.  
  763.   { PRETAB - Stop. } { Record required by Tab_Stop_Dialog. }
  764.  
  765.  
  766.  
  767. CONST { VMT constants. }
  768.  
  769.   REditor   : TStreamRec = (ObjType : 70;
  770.                             VmtLink : Ofs (TypeOf (TEditor)^);
  771.                                Load : @TEditor.Load;
  772.                               Store : @TEditor.Store);
  773.  
  774.  
  775.   RMemo     : TStreamRec = (ObjType : 71;
  776.                             VmtLink : Ofs (TypeOf (TMemo)^);
  777.                                Load : @TMemo.Load;
  778.                               Store : @TMemo.Store);
  779.  
  780.  
  781.   RFileEditor : TStreamRec = (ObjType : 72;
  782.                               VmtLink : Ofs (TypeOf (TFileEditor)^);
  783.                                  Load : @TFileEditor.Load;
  784.                                 Store : @TFileEditor.Store);
  785.  
  786.  
  787.   RIndicator : TStreamRec = (ObjType : 73;
  788.                              VmtLink : Ofs (TypeOf (TIndicator)^);
  789.                                 Load : @TIndicator.Load;
  790.                                Store : @TIndicator.Store);
  791.  
  792.  
  793.   REditWindow : TStreamRec = (ObjType : 74;
  794.                               VmtLink : Ofs (TypeOf (TEditWindow)^);
  795.                                  Load : @TEditWindow.Load;
  796.                                 Store : @TEditWindow.Store);
  797.  
  798.  
  799.  
  800. procedure RegisterEditors;
  801.  
  802.  
  803.  
  804.  
  805. implementation
  806.  
  807.  
  808.  
  809. uses
  810.  
  811.   Memory,
  812.   Buffers,
  813.   Dos;
  814.  
  815.  
  816.  
  817. CONST { Update flag constants. }
  818.  
  819.   ufUpdate = $01;
  820.   ufLine   = $02;
  821.   ufView   = $04;
  822.  
  823.   { STATS - Start. }
  824.  
  825.   ufStats  = $05;
  826.  
  827.   { STATS - Stop. }
  828.  
  829.  
  830.  
  831. CONST { SelectMode constants. }
  832.  
  833.   smExtend = $01;
  834.   smDouble = $02;
  835.  
  836.  
  837.  
  838. CONST
  839.  
  840.   sfSearchFailed = $FFFF;
  841.  
  842.  
  843.  
  844. CONST { Arrays that hold all the command keys and options. }
  845.  
  846.   { CTRLBK - Start. }
  847.   { HOMEND - Start. }
  848.   { INDENT - Start. }
  849.   { INSLIN - Start. }
  850.   { JLINE  - Start. }
  851.   { PRETAB - Start. }
  852.   { REFORM - Start. }
  853.   { SCRLDN - Start. }
  854.   { SCRLDN - Start. }
  855.  
  856.   FirstKeys : array[0..46 * 2] of Word = (46, Ord (^A),    cmWordLeft,
  857.                                               Ord (^B),    cmReformPara,
  858.                                               Ord (^C),    cmPageDown,
  859.                                               Ord (^D),    cmCharRight,
  860.                                               Ord (^E),    cmLineUp,
  861.                                               Ord (^F),    cmWordRight,
  862.                                               Ord (^G),    cmDelChar,
  863.                                               Ord (^H),    cmBackSpace,
  864.                                               Ord (^I),    cmTabKey,
  865.                                               Ord (^J),    $FF04,
  866.                                               Ord (^K),    $FF02,
  867.                                               Ord (^L),    cmSearchAgain,
  868.                                               Ord (^M),    cmNewLine,
  869.                                               Ord (^N),    cmInsertLine,
  870.                                               Ord (^O),    $FF03,
  871.                                               Ord (^Q),    $FF01,
  872.                                               Ord (^R),    cmPageUp,
  873.                                               Ord (^S),    cmCharLeft,
  874.                                               Ord (^T),    cmDelWord,
  875.                                               Ord (^U),    cmUndo,
  876.                                               Ord (^V),    cmInsMode,
  877.                                               Ord (^W),    cmScrollUp,
  878.                                               Ord (^X),    cmLineDown,
  879.                                               Ord (^Y),    cmDelLine,
  880.                                               Ord (^Z),    cmScrollDown,
  881.                                               kbLeft,      cmCharLeft,
  882.                                               kbRight,     cmCharRight,
  883.                                               kbCtrlLeft,  cmWordLeft,
  884.                                               kbCtrlRight, cmWordRight,
  885.                                               kbHome,      cmLineStart,
  886.                                               kbEnd,       cmLineEnd,
  887.                                               kbCtrlHome,  cmHomePage,
  888.                                               kbCtrlEnd,   cmEndPage,
  889.                                               kbUp,        cmLineUp,
  890.                                               kbDown,      cmLineDown,
  891.                                               kbPgUp,      cmPageUp,
  892.                                               kbPgDn,      cmPageDown,
  893.                                               kbCtrlPgUp,  cmTextStart,
  894.                                               kbCtrlPgDn,  cmTextEnd,
  895.                                               kbIns,       cmInsMode,
  896.                                               kbDel,       cmDelChar,
  897.                                               kbCtrlBack,  cmDelStart,
  898.                                               kbShiftIns,  cmPaste,
  899.                                               kbShiftDel,  cmCut,
  900.                                               kbCtrlIns,   cmCopy,
  901.                                               kbCtrlDel,   cmClear);
  902.  
  903.   { SCRLUP - Stop. } { Added ^W to scroll screen up.         }
  904.   { SCRLDN - Stop. } { Added ^Z to scroll screen down.       }
  905.   { REFORM - Stop. } { Added ^B for paragraph reformatting.  }
  906.   { PRETAB - Stop. } { Added ^I for preset tabbing.          }
  907.   { JLINE  - Stop. } { Added ^J to jump to a line number.    }
  908.   { INSLIN - Stop. } { Added ^N to insert line at cursor.    }
  909.   { INDENT - Stop. } { Removed ^O and put it into ^QI.       }
  910.   { HOMEND - Stop. } { Added kbCtrlHome and kbCtrlEnd pages. }
  911.   { CTRLBK - Stop. } { Added kbCtrlBack same as ^QH.         }
  912.  
  913.   { INDENT - Start. }
  914.   { MARK   - Start. }
  915.   { REFDOC - Start. }
  916.   { UNDO   - Start. }
  917.  
  918.   QuickKeys : array[0..21 * 2] of Word = (21, Ord ('0'), cmJumpMark0,
  919.                                               Ord ('1'), cmJumpMark1,
  920.                                               Ord ('2'), cmJumpMark2,
  921.                                               Ord ('3'), cmJumpMark3,
  922.                                               Ord ('4'), cmJumpMark4,
  923.                                               Ord ('5'), cmJumpMark5,
  924.                                               Ord ('6'), cmJumpMark6,
  925.                                               Ord ('7'), cmJumpMark7,
  926.                                               Ord ('8'), cmJumpMark8,
  927.                                               Ord ('9'), cmJumpMark9,
  928.                                               Ord ('A'), cmReplace,
  929.                                               Ord ('C'), cmTextEnd,
  930.                                               Ord ('D'), cmLineEnd,
  931.                                               Ord ('F'), cmFind,
  932.                                               Ord ('H'), cmDelStart,
  933.                                               Ord ('I'), cmIndentMode,
  934.                                               Ord ('L'), cmUndo,
  935.                                               Ord ('R'), cmTextStart,
  936.                                               Ord ('S'), cmLineStart,
  937.                                               Ord ('U'), cmReformDoc,
  938.                                               Ord ('Y'), cmDelEnd);
  939.  
  940.   { UNDO   - Stop. } { Added IDE undo feature of ^QL.                  }
  941.   { REFDOC - Stop. } { Added document reformat feature if ^QU pressed. }
  942.   { MARK   - Stop. } { Added cmJumpMark# to allow place marking.       }
  943.   { INDENT - Stop. } { Moved IndentMode here from Firstkeys.           }
  944.  
  945.   { MARK   - Start. }
  946.   { SAVE   - Start. }
  947.   { SELWRD - Start. }
  948.  
  949.   BlockKeys : array[0..20 * 2] of Word = (20, Ord ('0'), cmSetMark0,
  950.                                               Ord ('1'), cmSetMark1,
  951.                                               Ord ('2'), cmSetMark2,
  952.                                               Ord ('3'), cmSetMark3,
  953.                                               Ord ('4'), cmSetMark4,
  954.                                               Ord ('5'), cmSetMark5,
  955.                                               Ord ('6'), cmSetMark6,
  956.                                               Ord ('7'), cmSetMark7,
  957.                                               Ord ('8'), cmSetMark8,
  958.                                               Ord ('9'), cmSetMark9,
  959.                                               Ord ('B'), cmStartSelect,
  960.                                               Ord ('C'), cmPaste,
  961.                                               Ord ('D'), cmSave,
  962.                                               Ord ('F'), cmSaveAs,
  963.                                               Ord ('H'), cmHideSelect,
  964.                                               Ord ('K'), cmCopy,
  965.                                               Ord ('S'), cmSave,
  966.                                               Ord ('T'), cmSelectWord,
  967.                                               Ord ('Y'), cmCut,
  968.                                               Ord ('X'), cmSaveDone);
  969.  
  970.   { SELWRD - Stop. } { Added ^KT to select word only. }
  971.   { SAVE   - Stop. } { Added ^KD, ^KF, ^KS, ^KX key commands.   }
  972.   { MARK   - Stop. } { Added cmSetMark# to allow place marking. }
  973.  
  974.   { CENTER - Start. }
  975.   { PRETAB - Start. }
  976.   { RMSET  - Start. }
  977.   { WRAP   - Start. }
  978.  
  979.   FormatKeys : array[0..4 * 2] of Word = (4,  Ord ('C'), cmCenterText,
  980.                                               Ord ('I'), cmSetTabs,
  981.                                               Ord ('R'), cmRightMargin,
  982.                                               Ord ('W'), cmWordWrap);
  983.  
  984.   { WRAP   - Stop. } { Added Wordwrap feature if ^OW pressed.          }
  985.   { RMSET  - Stop. } { Added set right margin feature if ^OR pressed.  }
  986.   { PRETAB - Stop. } { Added preset tab feature if ^OI pressed.        }
  987.   { CENTER - Stop. } { Added center text option ^OC for a line.        }
  988.  
  989.  
  990.  
  991.   { JLINE - Start. }
  992.  
  993.   JumpKeys : array[0..1 * 2] of Word = (1, Ord ('L'), cmJumpLine);
  994.  
  995.   { JLINE - Stop. } { Added jump to line number feature if ^JL pressed. }
  996.  
  997.  
  998.  
  999.   { CENTER - Start. }
  1000.   { JLINE  - Start. }
  1001.   { PRETAB - Start. }
  1002.   { WRAP   - Start. }
  1003.  
  1004.   KeyMap : array[0..4] of Pointer = (@FirstKeys,
  1005.                                      @QuickKeys,
  1006.                                      @BlockKeys,
  1007.                                      @FormatKeys,
  1008.                                      @JumpKeys);
  1009.  
  1010.   { WRAP   - Stop. } { Added @FormatKeys for new ^O? keys. }
  1011.   { PRETAB - Stop. } { Added @FormatKeys for new ^O? keys. }
  1012.   { JLINE  - Stop. } { Added @JumpKeys for new ^J? keys.   }
  1013.   { CENTER - Stop. } { Added @FormatKeys for new ^O? keys. }
  1014.  
  1015.  
  1016.  
  1017. { -------------------------------------------------------------------------- }
  1018.  
  1019.  
  1020.  
  1021. function DefEditorDialog (Dialog : Integer; Info : Pointer) : Word;
  1022.  
  1023. begin
  1024.  
  1025.   DefEditorDialog := Views.cmCancel;
  1026.  
  1027.  
  1028. end; { DefEditorDialog }
  1029.  
  1030.  
  1031.  
  1032. { -------------------------------------------------------------------------- }
  1033.  
  1034.  
  1035.  
  1036. function Min (X, Y : Integer) : Integer; assembler;
  1037.  
  1038. asm
  1039.         MOV     AX,X
  1040.         CMP     AX,Y
  1041.         JLE     @@1
  1042.         MOV     AX,Y
  1043. @@1:
  1044.  
  1045.  
  1046. end; { Min }
  1047.  
  1048.  
  1049.  
  1050. { -------------------------------------------------------------------------- }
  1051.  
  1052.  
  1053.  
  1054. function Max (X, Y : Integer) : Integer; assembler;
  1055.  
  1056. asm
  1057.         MOV     AX,X
  1058.         CMP     AX,Y
  1059.         JGE     @@1
  1060.         MOV     AX,Y
  1061. @@1:
  1062.  
  1063.  
  1064. end; { Max }
  1065.  
  1066.  
  1067.  
  1068. { -------------------------------------------------------------------------- }
  1069.  
  1070.  
  1071.  
  1072. function MinWord (X, Y : Word) : Word; assembler;
  1073.  
  1074. asm
  1075.         MOV     AX,X
  1076.         CMP     AX,Y
  1077.         JBE     @@1
  1078.         MOV     AX,Y
  1079. @@1:
  1080.  
  1081.  
  1082. end; { MinWord }
  1083.  
  1084.  
  1085.  
  1086. { -------------------------------------------------------------------------- }
  1087.  
  1088.  
  1089.  
  1090. function MaxWord (X, Y : Word) : Word; assembler;
  1091.  
  1092. asm
  1093.         MOV     AX,X
  1094.         CMP     AX,Y
  1095.         JAE     @@1
  1096.         MOV     AX,Y
  1097. @@1:
  1098.  
  1099.  
  1100. end; { MaxWord }
  1101.  
  1102.  
  1103.  
  1104. { -------------------------------------------------------------------------- }
  1105.  
  1106.  
  1107.  
  1108. function CountLines (var Buf; Count : Word) : Integer; assembler;
  1109.  
  1110. asm
  1111.         LES     DI,Buf
  1112.         MOV     CX,Count
  1113.         XOR     DX,DX
  1114.         MOV     AL,0DH
  1115.         CLD
  1116. @@1:    JCXZ    @@2
  1117.         REPNE   SCASB
  1118.         JNE     @@2
  1119.         INC     DX
  1120.         JMP     @@1
  1121. @@2:    MOV     AX,DX
  1122.  
  1123.  
  1124. end; { CountLines }
  1125.  
  1126.  
  1127.  
  1128. { -------------------------------------------------------------------------- }
  1129.  
  1130.  
  1131.  
  1132. function ScanKeyMap (KeyMap : Pointer; KeyCode : Word) : Word; assembler;
  1133.  
  1134. asm
  1135.         PUSH    DS
  1136.         LDS     SI,KeyMap
  1137.         MOV     DX,KeyCode
  1138.         CLD
  1139.         LODSW
  1140.         MOV     CX,AX
  1141. @@1:    LODSW
  1142.         MOV     BX,AX
  1143.         LODSW
  1144.         CMP     BL,DL
  1145.         JNE     @@3
  1146.         OR      BH,BH
  1147.         JE      @@4
  1148.         CMP     BH,DH
  1149.         JE      @@4
  1150. @@3:    LOOP    @@1
  1151.         XOR     AX,AX
  1152. @@4:    POP     DS
  1153.  
  1154.  
  1155. end; { ScanKeyMap }
  1156.  
  1157.  
  1158.  
  1159. { -------------------------------------------------------------------------- }
  1160.  
  1161.  
  1162.  
  1163. function Scan (var Block; Size : Word; Str : String) : Word; assembler;
  1164.  
  1165. asm
  1166.         PUSH    DS
  1167.         LES     DI,Block
  1168.         LDS     SI,Str
  1169.         MOV     CX,Size
  1170.         JCXZ    @@3
  1171.         CLD
  1172.         LODSB
  1173.         CMP     AL,1
  1174.         JB      @@5
  1175.         JA      @@1
  1176.         LODSB
  1177.         REPNE   SCASB
  1178.         JNE     @@3
  1179.         JMP     @@5
  1180. @@1:    XOR     AH,AH
  1181.         MOV     BX,AX
  1182.         DEC     BX
  1183.         MOV     DX,CX
  1184.         SUB     DX,AX
  1185.         JB      @@3
  1186.         LODSB
  1187.         INC     DX
  1188.         INC     DX
  1189. @@2:    DEC     DX
  1190.         MOV     CX,DX
  1191.         REPNE   SCASB
  1192.         JNE     @@3
  1193.         MOV     DX,CX
  1194.         MOV     CX,BX
  1195.         REP     CMPSB
  1196.         JE      @@4
  1197.         SUB     CX,BX
  1198.         ADD     SI,CX
  1199.         ADD     DI,CX
  1200.         INC     DI
  1201.         OR      DX,DX
  1202.         JNE     @@2
  1203. @@3:    XOR     AX,AX
  1204.         JMP     @@6
  1205. @@4:    SUB     DI,BX
  1206. @@5:    MOV     AX,DI
  1207.         SUB     AX,WORD PTR Block
  1208. @@6:    DEC     AX
  1209.         POP     DS
  1210.  
  1211.  
  1212. end; { Scan }
  1213.  
  1214.  
  1215.  
  1216. { -------------------------------------------------------------------------- }
  1217.  
  1218.  
  1219.  
  1220. function IScan (var Block; Size : Word; Str : String) : Word; assembler;
  1221.  
  1222. VAR
  1223.  
  1224.   S : String;
  1225.  
  1226. asm
  1227.         PUSH    DS
  1228.         MOV     AX,SS
  1229.         MOV     ES,AX
  1230.         LEA     DI,S
  1231.         LDS     SI,Str
  1232.         XOR     AH,AH
  1233.         LODSB
  1234.         STOSB
  1235.         MOV     CX,AX
  1236.         MOV     BX,AX
  1237.         JCXZ    @@9
  1238. @@1:    LODSB
  1239.         CMP     AL,'a'
  1240.         JB      @@2
  1241.         CMP     AL,'z'
  1242.         JA      @@2
  1243.         SUB     AL,20H
  1244. @@2:    STOSB
  1245.         LOOP    @@1
  1246.         SUB     DI,BX
  1247.         LDS     SI,Block
  1248.         MOV     CX,Size
  1249.         JCXZ    @@8
  1250.         CLD
  1251.         SUB     CX,BX
  1252.         JB      @@8
  1253.         INC     CX
  1254. @@4:    MOV     AH,ES:[DI]
  1255.         AND     AH,$DF
  1256. @@5:    LODSB
  1257.         AND     AL,$DF
  1258.         CMP     AL,AH
  1259.         LOOPNE  @@5
  1260.         JNE     @@8
  1261.         DEC     SI
  1262.         MOV     DX,CX
  1263.         MOV     CX,BX
  1264. @@6:    REPE    CMPSB
  1265.         JE      @@10
  1266.         MOV     AL,DS:[SI-1]
  1267.         CMP     AL,'a'
  1268.         JB      @@7
  1269.         CMP     AL,'z'
  1270.         JA      @@7
  1271.         SUB     AL,20H
  1272. @@7:    CMP     AL,ES:[DI-1]
  1273.         JE      @@6
  1274.         SUB     CX,BX
  1275.         ADD     SI,CX
  1276.         ADD     DI,CX
  1277.         INC     SI
  1278.         MOV     CX,DX
  1279.         TEST    CX,CX
  1280.         JNE     @@4
  1281. @@8:    XOR     AX,AX
  1282.         JMP     @@11
  1283. @@9:    MOV     AX, 1
  1284.         JMP     @@11
  1285. @@10:   SUB     SI,BX
  1286.         MOV     AX,SI
  1287.         SUB     AX,WORD PTR Block
  1288.         INC     AX
  1289. @@11:   DEC     AX
  1290.         POP     DS
  1291.  
  1292.  
  1293. end; { Iscan }
  1294.  
  1295.  
  1296.  
  1297. { -------------------------------------------------------------------------- }
  1298.  
  1299.  
  1300.  
  1301.          { ---------------------------------------------------- }
  1302.          {                                                      }
  1303.          { The following methods are for the TINDICATOR object. }
  1304.          {                                                      }
  1305.          { ---------------------------------------------------- }
  1306.  
  1307.  
  1308.  
  1309. constructor TIndicator.Init (var Bounds : TRect);
  1310.  
  1311. VAR
  1312.  
  1313.   R : TRect;
  1314.  
  1315. begin
  1316.  
  1317.   TView.Init (Bounds);
  1318.   GrowMode := gfGrowLoY + gfGrowHiY;
  1319.  
  1320.  
  1321.  
  1322. end; { TIndicator.Init }
  1323.  
  1324.  
  1325.  
  1326. { -------------------------------------------------------------------------- }
  1327.  
  1328.  
  1329.  
  1330. procedure TIndicator.Draw;
  1331.  
  1332. VAR
  1333.  
  1334.   Color : Byte;
  1335.   Frame : Char;
  1336.   L     : array[0..1] of Longint;
  1337.   S     : String[15];
  1338.   B     : Views.TDrawBuffer;
  1339.  
  1340. begin
  1341.  
  1342.   if State and sfDragging = 0 then
  1343.     begin
  1344.       Color := GetColor (1);
  1345.       Frame := #205;
  1346.     end
  1347.   else
  1348.     begin
  1349.       Color := GetColor (2);
  1350.       Frame := #196;
  1351.     end;
  1352.  
  1353.   MoveChar (B, Frame, Color, Size.X);
  1354.  
  1355.  
  1356.  
  1357.   { STATS - Start. }
  1358.  
  1359.   { -------------------------------------------------------------------- }
  1360.   {                                                                      }
  1361.   { If the text has been modified, put an 'M' in the TIndicator display. }
  1362.   {                                                                      }
  1363.   { -------------------------------------------------------------------- }
  1364.  
  1365.  
  1366.   if Modified then
  1367.     WordRec (B[1]).Lo := 77;
  1368.  
  1369.  
  1370.  
  1371.   { ---------------------------------------------------------- }
  1372.   {                                                            }
  1373.   { If WordWrap is active put a 'W' in the TIndicator display. }
  1374.   { Otherwise, just use the current frame character.           }
  1375.   {                                                            }
  1376.   { ---------------------------------------------------------- }
  1377.  
  1378.  
  1379.   if WordWrap then
  1380.     WordRec (B[2]).Lo := 87
  1381.   else
  1382.     WordRec (B[2]).Lo := Byte (Frame);
  1383.  
  1384.  
  1385.  
  1386.   { --------------------------------------------------------- }
  1387.   {                                                           }
  1388.   { If AutoIndent is active put an 'I' in TIndicator display. }
  1389.   { Otherwise, just use the current frame character.          }
  1390.   {                                                           }
  1391.   { --------------------------------------------------------- }
  1392.  
  1393.  
  1394.   if AutoIndent then
  1395.     WordRec (B[0]).Lo := 73
  1396.   else
  1397.     WordRec (B[0]).Lo := Byte (Frame);
  1398.  
  1399.   L[0] := Location.Y + 1;
  1400.   L[1] := Location.X + 1;
  1401.  
  1402.   FormatStr (S, ' %d:%d ', L);
  1403.   MoveStr (B[9 - Pos (':', S)], S, Color);       { Changed original 8 to 9. }
  1404.   WriteBuf (0, 0, Size.X, 1, B);
  1405.  
  1406.   { STATS - Stop. } { Changed who goes where in B array and added new code. }
  1407.  
  1408.  
  1409. end; { TIndicator.Draw }
  1410.  
  1411.  
  1412.  
  1413. { -------------------------------------------------------------------------- }
  1414.  
  1415.  
  1416.  
  1417. function TIndicator.GetPalette : Views.PPalette;
  1418.  
  1419. CONST
  1420.  
  1421.   P : string[Length (CIndicator)] = CIndicator;
  1422.  
  1423. begin
  1424.  
  1425.   GetPalette := @P;
  1426.  
  1427.  
  1428. end; { TIndicator.GetPalette }
  1429.  
  1430.  
  1431.  
  1432. { -------------------------------------------------------------------------- }
  1433.  
  1434.  
  1435.  
  1436. procedure TIndicator.SetState (AState : Word; Enable : Boolean);
  1437.  
  1438. begin
  1439.  
  1440.   TView.SetState (AState, Enable);
  1441.   if AState = sfDragging
  1442.     then DrawView;
  1443.  
  1444.  
  1445. end; { TIndicator.SetState }
  1446.  
  1447.  
  1448.  
  1449. { -------------------------------------------------------------------------- }
  1450.  
  1451.  
  1452.  
  1453. { STATS - Start. }
  1454.  
  1455. procedure TIndicator.SetValue (ALocation : Objects.TPoint; IsAutoIndent : Boolean;
  1456.                                                            IsModified   : Boolean;
  1457.                                                            IsWordWrap   : Boolean);
  1458.  
  1459. begin
  1460.  
  1461.   if   (Longint (Location) <> Longint (ALocation))
  1462.     or (AutoIndent <> IsAutoIndent)
  1463.     or (Modified <> IsModified)
  1464.     or (WordWrap <> IsWordWrap) then
  1465.   begin
  1466.     Location   := ALocation;
  1467.     AutoIndent := IsAutoIndent;    { Added provisions to show AutoIndent. }
  1468.     Modified   := IsModified;
  1469.     WordWrap   := IsWordWrap;      { Added provisions to show WordWrap.   }
  1470.  
  1471.     DrawView;
  1472.   end;
  1473.  
  1474.  
  1475. end; { TIndicator.SetValue }
  1476.  
  1477. { STATS - Stop. } { Changed parameter calls to show them on TIndicator line. }
  1478.  
  1479.  
  1480.  
  1481. { -------------------------------------------------------------------------- }
  1482.  
  1483.  
  1484.  
  1485.          { ------------------------------------------------- }
  1486.          {                                                   }
  1487.          { The following methods are for the TEDITOR object. }
  1488.          {                                                   }
  1489.          { ------------------------------------------------- }
  1490.  
  1491.  
  1492.  
  1493. constructor TEditor.Init (var Bounds : TRect;
  1494.                               AHScrollBar, AVScrollBar : PScrollBar;
  1495.                               AIndicator : PIndicator; ABufSize : Word);
  1496.  
  1497. { MARK - Start. }
  1498.  
  1499. VAR
  1500.  
  1501.   Element : Byte;      { Place_Marker array element to initialize array with. }
  1502.  
  1503. { MARK - Stop. } { Added Element variable. }
  1504.  
  1505. begin
  1506.  
  1507.   TView.Init (Bounds);
  1508.   GrowMode := gfGrowHiX + gfGrowHiY;
  1509.   Options := Options or ofSelectable;
  1510.   EventMask := evMouseDown + evKeyDown + evCommand + evBroadcast;
  1511.   ShowCursor;
  1512.  
  1513.   HScrollBar := AHScrollBar;
  1514.   VScrollBar := AVScrollBar;
  1515.  
  1516.   Indicator := AIndicator;
  1517.   BufSize := ABufSize;
  1518.   CanUndo := True;
  1519.   InitBuffer;
  1520.  
  1521.   if Buffer <> nil then
  1522.     IsValid := True
  1523.   else
  1524.     begin
  1525.       EditorDialog (edOutOfMemory, nil);
  1526.       BufSize := 0;
  1527.     end;
  1528.  
  1529.   SetBufLen (0);
  1530.  
  1531.   { MARK - Start. }
  1532.  
  1533.   for Element := 1 to 10 do
  1534.     Place_Marker[Element] := 0;
  1535.  
  1536.   { MARK - Stop. } { Added code to initialize Place_Marker array to zero's. }
  1537.  
  1538.   { PRETAB - Start. }
  1539.  
  1540.   Element := 1;
  1541.  
  1542.   while Element <= 70 do
  1543.     begin
  1544.       if Element mod 5 = 0 then
  1545.         Insert ('x', Tab_Settings, Element)
  1546.       else
  1547.         Insert (#32, Tab_Settings, Element);
  1548.       Inc (Element);
  1549.     end;
  1550.  
  1551.   { PRETAB - Stop. }
  1552.  
  1553.   { WRAP - Start. }
  1554.  
  1555.   Right_Margin := 76; { Default Right_Margin value.  Change it if you want another. }
  1556.  
  1557.   { WRAP - Stop. }
  1558.  
  1559.  
  1560. end; { TEditor.Init }
  1561.  
  1562.  
  1563.  
  1564. { -------------------------------------------------------------------------- }
  1565.  
  1566.  
  1567.  
  1568. constructor TEditor.Load (var S : Objects.TStream);
  1569.  
  1570. begin
  1571.  
  1572.   TView.Load (S);
  1573.  
  1574.   GetPeerViewPtr (S, HScrollBar);
  1575.   GetPeerViewPtr (S, VScrollBar);
  1576.   GetPeerViewPtr (S, Indicator);
  1577.   S.Read (BufSize, SizeOf (Word));
  1578.  
  1579.  
  1580.   { LOAD - Start. }
  1581.  
  1582.   { S.Read (CanUndo, SizeOf (Boolean)); }
  1583.  
  1584.   { LOAD - Stop. } { This item caused load/store bug. }
  1585.  
  1586.  
  1587.   { STATS  - Start. }
  1588.   { JLINE  - Start. }
  1589.   { MARK   - Start. }
  1590.   { RMSET  - Start. }
  1591.   { PRETAB - Start. }
  1592.   { WRAP   - Start. }
  1593.  
  1594.   S.Read (AutoIndent,   SizeOf (AutoIndent));
  1595.   S.Read (Line_Number,  SizeOf (Line_Number));
  1596.   S.Read (Place_Marker, SizeOf (Place_Marker));
  1597.   S.Read (Right_Margin, SizeOf (Right_Margin));
  1598.   S.Read (Tab_Settings, SizeOf (Tab_Settings));
  1599.   S.Read (Word_Wrap,    SizeOf (Word_Wrap));
  1600.  
  1601.   CanUndo := True;
  1602.  
  1603.   { WRAP   - Stop. }
  1604.   { PRETAB - Stop. }
  1605.   { RMSET  - Stop. }
  1606.   { MARK   - Stop. }
  1607.   { JLINE  - Stop. }
  1608.   { STATS  - Stop. } { Added these to allow load/store operations. }
  1609.  
  1610.   InitBuffer;
  1611.  
  1612.   if Buffer <> nil then
  1613.     IsValid := True
  1614.   else
  1615.     begin
  1616.       EditorDialog (edOutOfMemory, nil);
  1617.       BufSize := 0;
  1618.     end;
  1619.  
  1620.   Lock;
  1621.  
  1622.   SetBufLen (0);
  1623.  
  1624.  
  1625. end; { TEditor.Load }
  1626.  
  1627.  
  1628.  
  1629. { -------------------------------------------------------------------------- }
  1630.  
  1631.  
  1632.  
  1633. destructor TEditor.Done;
  1634.  
  1635. begin
  1636.  
  1637.   DoneBuffer;
  1638.   TView.Done;
  1639.  
  1640.  
  1641. end; { TEditor.Done }
  1642.  
  1643.  
  1644.  
  1645. { -------------------------------------------------------------------------- }
  1646.  
  1647.  
  1648.  
  1649. function TEditor.BufChar (P : Word) : Char; assembler;
  1650.  
  1651. asm
  1652.         LES     DI,Self
  1653.         MOV     BX,P
  1654.         CMP     BX,ES:[DI].TEditor.CurPtr
  1655.         JB      @@1
  1656.         ADD     BX,ES:[DI].TEditor.GapLen
  1657. @@1:    LES     DI,ES:[DI].TEditor.Buffer
  1658.         MOV     AL,ES:[DI+BX]
  1659.  
  1660.  
  1661. end; { TEditor.BufChar }
  1662.  
  1663.  
  1664.  
  1665. { -------------------------------------------------------------------------- }
  1666.  
  1667.  
  1668.  
  1669. function TEditor.BufPtr (P : Word) : Word; assembler;
  1670.  
  1671. asm
  1672.         LES     DI,Self
  1673.         MOV     AX,P
  1674.         CMP     AX,ES:[DI].TEditor.CurPtr
  1675.         JB      @@1
  1676.         ADD     AX,ES:[DI].TEditor.GapLen
  1677. @@1:
  1678.  
  1679.  
  1680. end; { TEditor.BufPtr }
  1681.  
  1682.  
  1683.  
  1684. { -------------------------------------------------------------------------- }
  1685.  
  1686.  
  1687.  
  1688. { CENTER - Start. }
  1689.  
  1690. procedure TEditor.Center_Text (Select_Mode : Byte);
  1691.  
  1692.  
  1693.   { ---------------------------------------------------- }
  1694.   {                                                      }
  1695.   { This procedure will center the current line of text. }
  1696.   { Centering is based on the current Right_Margin.      }
  1697.   { If the Line_Length exceeds the Right_Margin, or the  }
  1698.   { line is just a blank line, we exit and do nothing.   }
  1699.   {                                                      }
  1700.   { ---------------------------------------------------- }
  1701.  
  1702.  
  1703. VAR
  1704.  
  1705.   Spaces      : array [1..80] of Char;  { Array to hold spaces we'll insert. }
  1706.   Index       : Byte;                   { Index into Spaces array.           }
  1707.   Line_Length : Integer;                { Holds the length of the line.      }
  1708.  
  1709.   E : Word;                             { End of the current line.           }
  1710.   S : Word;                             { Start of the current line.         }
  1711.  
  1712. begin
  1713.  
  1714.   E := LineEnd (CurPtr);
  1715.   S := LineStart (CurPtr);
  1716.  
  1717.  
  1718.  
  1719.   { --------------------------------------------------------- }
  1720.   {                                                           }
  1721.   { If the line is blank (only a CR/LF on it) then do noting. }
  1722.   {                                                           }
  1723.   { --------------------------------------------------------- }
  1724.  
  1725.  
  1726.   if E = S then
  1727.     Exit;
  1728.  
  1729.  
  1730.  
  1731.   { ----------------------------------------------------------------- }
  1732.   {                                                                   }
  1733.   { Set CurPtr to start of line.  Check if line begins with a space.  }
  1734.   { We must strip out any spaces from the beginning, or end of lines. }
  1735.   { If line does not start with space, make sure line length does not }
  1736.   { exceed the Right_Margin.  If it does, then do nothing.            }
  1737.   {                                                                   }
  1738.   { ----------------------------------------------------------------- }
  1739.  
  1740.  
  1741.   SetCurPtr (S, Select_Mode);
  1742.   Remove_EOL_Spaces (Select_Mode);
  1743.  
  1744.   if Buffer^[CurPtr] = #32 then
  1745.     begin
  1746.  
  1747.  
  1748.  
  1749.       { ----------------------------------------------------------------- }
  1750.       {                                                                   }
  1751.       { If the next word is greater than the end of line then do nothing. }
  1752.       { If the line length is greater than Right_Margin then do nothing.  }
  1753.       { Otherwise, delete all spaces at the start of line.                }
  1754.       { Then reset end of line and put CurPtr at start of modified line.  }
  1755.       {                                                                   }
  1756.       { ----------------------------------------------------------------- }
  1757.  
  1758.       E := LineEnd (CurPtr);
  1759.  
  1760.       if NextWord (CurPtr) > E then
  1761.         Exit;
  1762.       if E - NextWord (CurPtr) > Right_Margin then
  1763.         Exit;
  1764.  
  1765.       DeleteRange (CurPtr, NextWord (CurPtr), True);
  1766.  
  1767.       E := LineEnd (CurPtr);
  1768.       SetCurPtr (LineStart (CurPtr), Select_Mode);
  1769.  
  1770.     end
  1771.   else
  1772.     if E - CurPtr > Right_Margin then
  1773.       Exit;
  1774.  
  1775.  
  1776.  
  1777.   { --------------------------------------------------- }
  1778.   {                                                     }
  1779.   { Now we determine the real length of the line.       }
  1780.   { Then we subtract the Line_Length from Right_Margin. }
  1781.   { Dividing the result by two tells us how many spaces }
  1782.   { must be inserted at start of line to center it.     }
  1783.   { When we're all done, set the CurPtr to end of line. }
  1784.   {                                                     }
  1785.   { --------------------------------------------------- }
  1786.  
  1787.  
  1788.   Line_Length := E - CurPtr;
  1789.  
  1790.   for Index := 1 to ((Right_Margin - Line_Length) DIV 2) do
  1791.     Spaces[Index] := #32;
  1792.  
  1793.   InsertText (@Spaces, Index, False);
  1794.   SetCurPtr (LineEnd (CurPtr), Select_Mode);
  1795.  
  1796.  
  1797. end; { TEditor.Center_Text }
  1798.  
  1799. { CENTER - Stop. }
  1800.  
  1801.  
  1802.  
  1803. { -------------------------------------------------------------------------- }
  1804.  
  1805.  
  1806.  
  1807. procedure TEditor.ChangeBounds (var Bounds : TRect);
  1808.  
  1809. begin
  1810.  
  1811.   SetBounds (Bounds);
  1812.   Delta.X := Max (0, Min (Delta.X, Limit.X - Size.X));
  1813.   Delta.Y := Max (0, Min (Delta.Y, Limit.Y - Size.Y));
  1814.   Update (ufView);
  1815.  
  1816.  
  1817. end; { TEditor.ChangeBounds }
  1818.  
  1819.  
  1820.  
  1821. { -------------------------------------------------------------------------- }
  1822.  
  1823.  
  1824.  
  1825. function TEditor.CharPos (P, Target : Word) : Integer;
  1826.  
  1827. VAR
  1828.  
  1829.   Pos : Integer;
  1830.  
  1831. begin
  1832.  
  1833.   Pos := 0;
  1834.  
  1835.   while P < Target do
  1836.   begin
  1837.     if BufChar (P) = #9 then
  1838.       Pos := Pos or 7;
  1839.     Inc (Pos);
  1840.     Inc (P);
  1841.   end;
  1842.  
  1843.   CharPos := Pos;
  1844.  
  1845.  
  1846. end; { TEditor.CharPos }
  1847.  
  1848.  
  1849.  
  1850. { -------------------------------------------------------------------------- }
  1851.  
  1852.  
  1853.  
  1854. function TEditor.CharPtr (P : Word; Target : Integer) : Word;
  1855.  
  1856. VAR
  1857.  
  1858.   Pos : Integer;
  1859.  
  1860. begin
  1861.  
  1862.   Pos := 0;
  1863.  
  1864.   while (Pos < Target) and (P < BufLen) and (BufChar (P) <> #13) do
  1865.   begin
  1866.     if BufChar (P) = #9 then
  1867.       Pos := Pos or 7;
  1868.     Inc (Pos);
  1869.     Inc (P);
  1870.   end;
  1871.  
  1872.   if Pos > Target then
  1873.     Dec (P);
  1874.  
  1875.   CharPtr := P;
  1876.  
  1877.  
  1878. end; { TEditor.CharPtr }
  1879.  
  1880.  
  1881.  
  1882. { -------------------------------------------------------------------------- }
  1883.  
  1884.  
  1885.  
  1886. { WRAP - Start. }
  1887.  
  1888. procedure TEditor.Check_For_Word_Wrap (Select_Mode   : Byte;
  1889.                                        Center_Cursor : Boolean);
  1890.  
  1891.  
  1892.  
  1893.   { ------------------------------------------------- }
  1894.   {                                                   }
  1895.   { This procedure checks if CurPos.X > Right_Margin. }
  1896.   { If it is, then we Do_Word_Wrap.  Simple, eh?      }
  1897.   {                                                   }
  1898.   { ------------------------------------------------- }
  1899.  
  1900. begin
  1901.  
  1902.   if CurPos.X > Right_Margin then
  1903.     Do_Word_Wrap (Select_Mode, Center_Cursor);
  1904.  
  1905.  
  1906. end; {Check_For_Word_Wrap}
  1907.  
  1908. { WRAP - Stop. }
  1909.  
  1910.  
  1911.  
  1912. { -------------------------------------------------------------------------- }
  1913.  
  1914.  
  1915.  
  1916. function TEditor.ClipCopy : Boolean;
  1917.  
  1918. begin
  1919.  
  1920.   ClipCopy := False;
  1921.  
  1922.   if (Clipboard <> nil) and (Clipboard <> @Self) then
  1923.   begin
  1924.     ClipCopy := Clipboard^.InsertFrom (@Self);
  1925.     Selecting := False;
  1926.     Update (ufUpdate);
  1927.   end;
  1928.  
  1929.  
  1930. end; { TEditor.ClipCopy }
  1931.  
  1932.  
  1933.  
  1934. { -------------------------------------------------------------------------- }
  1935.  
  1936.  
  1937.  
  1938. procedure TEditor.ClipCut;
  1939.  
  1940. begin
  1941.  
  1942.   if ClipCopy then
  1943.   begin
  1944.  
  1945.     { MARK - Start. }
  1946.  
  1947.     Update_Place_Markers (0,
  1948.                           Self.SelEnd - Self.SelStart,
  1949.                           Self.SelStart,
  1950.                           Self.SelEnd);
  1951.     { MARK - Stop. }
  1952.  
  1953.     DeleteSelect;
  1954.  
  1955.   end;
  1956.  
  1957.  
  1958. end; { TEditor.ClipCut }
  1959.  
  1960.  
  1961.  
  1962. { -------------------------------------------------------------------------- }
  1963.  
  1964.  
  1965.  
  1966. procedure TEditor.ClipPaste;
  1967.  
  1968. begin
  1969.  
  1970.  
  1971.  
  1972.   if (Clipboard <> nil) and (Clipboard <> @Self) then
  1973.     begin
  1974.  
  1975.  
  1976.  
  1977.       { WRAP - Start. }
  1978.  
  1979.       { ---------------------------------------------- }
  1980.       {                                                }
  1981.       { Do not allow paste operations that will exceed }
  1982.       { the Right_Margin when Word_Wrap is active and  }
  1983.       { cursor is at EOL.                              }
  1984.       {                                                }
  1985.       { ---------------------------------------------- }
  1986.  
  1987.  
  1988.       if Word_Wrap and (CurPos.X > Right_Margin) then
  1989.  
  1990.         begin
  1991.           EditorDialog (edPasteNotPossible, nil);
  1992.           Exit;
  1993.         end;
  1994.  
  1995.       { WRAP - Stop. }
  1996.  
  1997.  
  1998.  
  1999.       { MARK - Start. }
  2000.  
  2001.       { ---------------------------------------------------- }
  2002.       {                                                      }
  2003.       { The editor will not copy selected text if the CurPtr }
  2004.       { is not the same value as the SelStart.  However, it  }
  2005.       { does return an InsCount.  This may, or may not, be a }
  2006.       { bug.  We don't want to update the Place_Marker if    }
  2007.       { there's no text copied.                              }
  2008.       {                                                      }
  2009.       { ---------------------------------------------------- }
  2010.  
  2011.       if CurPtr = SelStart then
  2012.  
  2013.         Update_Place_Markers (Clipboard^.SelEnd - Clipboard^.SelStart,
  2014.                               0,
  2015.                               Clipboard^.SelStart,
  2016.                               Clipboard^.SelEnd);
  2017.  
  2018.       { MARK - Stop. }
  2019.  
  2020.       InsertFrom (Clipboard);
  2021.  
  2022.  
  2023.     end;
  2024.  
  2025.  
  2026. end; { TEditor.ClipPaste }
  2027.  
  2028.  
  2029.  
  2030. { -------------------------------------------------------------------------- }
  2031.  
  2032.  
  2033.  
  2034. procedure TEditor.ConvertEvent (var Event : Drivers.TEvent);
  2035.  
  2036. VAR
  2037.  
  2038.   ShiftState : Byte absolute $40:$17;
  2039.   Key        : Word;
  2040.  
  2041.  
  2042. begin
  2043.  
  2044.   if Event.What = evKeyDown then
  2045.   begin
  2046.  
  2047.     if (ShiftState and $03 <> 0)
  2048.                    and (Event.ScanCode >= $47)
  2049.                    and (Event.ScanCode <= $51) then
  2050.       Event.CharCode := #0;
  2051.  
  2052.     Key := Event.KeyCode;
  2053.  
  2054.     if KeyState <> 0 then
  2055.     begin
  2056.       if (Lo (Key) >= $01) and (Lo (Key) <= $1A) then
  2057.         Inc (Key, $40);
  2058.       if (Lo (Key) >= $61) and (Lo (Key) <= $7A) then
  2059.         Dec (Key, $20);
  2060.     end;
  2061.  
  2062.     Key := ScanKeyMap (KeyMap[KeyState], Key);
  2063.     KeyState := 0;
  2064.  
  2065.     if Key <> 0 then
  2066.       if Hi (Key) = $FF then
  2067.         begin
  2068.           KeyState := Lo (Key);
  2069.           ClearEvent (Event);
  2070.         end
  2071.       else
  2072.         begin
  2073.           Event.What := evCommand;
  2074.           Event.Command := Key;
  2075.         end;
  2076.   end;
  2077.  
  2078.  
  2079. end; { TEditor.ConvertEvent }
  2080.  
  2081.  
  2082.  
  2083. { -------------------------------------------------------------------------- }
  2084.  
  2085.  
  2086.  
  2087. function TEditor.CursorVisible : Boolean;
  2088.  
  2089. begin
  2090.  
  2091.   CursorVisible := (CurPos.Y >= Delta.Y) and (CurPos.Y < Delta.Y + Size.Y);
  2092.  
  2093. end; { TEditor.CursorVisible }
  2094.  
  2095.  
  2096.  
  2097. { -------------------------------------------------------------------------- }
  2098.  
  2099.  
  2100.  
  2101. procedure TEditor.DeleteRange (StartPtr, EndPtr : Word; DelSelect : Boolean);
  2102.  
  2103.  
  2104. begin
  2105.  
  2106.   { MARK - Start. }
  2107.  
  2108.   Update_Place_Markers (0, EndPtr - StartPtr, StartPtr, EndPtr);
  2109.  
  2110.   { MARK - Stop. } { This will update Place_Marker for all deletions. }
  2111.                    { EXCEPT the Remove_EOL_Spaces deletion.           }
  2112.  
  2113.   if HasSelection and DelSelect then
  2114.     DeleteSelect
  2115.   else
  2116.     begin
  2117.       SetSelect (CurPtr, EndPtr, True);
  2118.       DeleteSelect;
  2119.       SetSelect (StartPtr, CurPtr, False);
  2120.       DeleteSelect;
  2121.     end;
  2122.  
  2123.  
  2124. end; { TEditor.DeleteRange }
  2125.  
  2126.  
  2127.  
  2128. { -------------------------------------------------------------------------- }
  2129.  
  2130.  
  2131.  
  2132. procedure TEditor.DeleteSelect;
  2133.  
  2134. begin
  2135.  
  2136.   InsertText (nil, 0, False);
  2137.  
  2138. end; { TEditor.DeleteSelect }
  2139.  
  2140.  
  2141.  
  2142. { -------------------------------------------------------------------------- }
  2143.  
  2144.  
  2145. procedure TEditor.DoneBuffer;
  2146.  
  2147. begin
  2148.  
  2149.   if Buffer <> nil then
  2150.     FreeMem (Buffer, BufSize);
  2151.  
  2152. end; { TEditor.DoneBuffer }
  2153.  
  2154.  
  2155.  
  2156. { -------------------------------------------------------------------------- }
  2157.  
  2158.  
  2159.  
  2160. procedure TEditor.DoSearchReplace;
  2161.  
  2162. VAR
  2163.  
  2164.   I : Word;
  2165.   C : Objects.TPoint;
  2166.  
  2167. begin
  2168.   repeat
  2169.  
  2170.     I := Views.cmCancel;
  2171.  
  2172.     if not Search (FindStr, EditorFlags) then
  2173.       begin
  2174.         if EditorFlags and (efReplaceAll + efDoReplace) <>
  2175.             (efReplaceAll + efDoReplace) then
  2176.           EditorDialog (edSearchFailed, nil)
  2177.       end
  2178.     else
  2179.  
  2180.       if EditorFlags and efDoReplace <> 0 then
  2181.       begin
  2182.  
  2183.         I := cmYes;
  2184.         if EditorFlags and efPromptOnReplace <> 0 then
  2185.         begin
  2186.           MakeGlobal (Cursor, C);
  2187.           I := EditorDialog (edReplacePrompt, Pointer (C));
  2188.         end;
  2189.  
  2190.         if I = cmYes then
  2191.           begin
  2192.  
  2193.             { WRAP - Start. }
  2194.  
  2195.             { ---------------------------------------- }
  2196.             {                                          }
  2197.             { If Word_Wrap is active and we are at EOL }
  2198.             { disallow replace by bringing up a dialog }
  2199.             { stating that replace is not possible.    }
  2200.             {                                          }
  2201.             { ---------------------------------------- }
  2202.  
  2203.             if Word_Wrap and
  2204.                ((CurPos.X + (Length (ReplaceStr) - Length (FindStr))) > Right_Margin) then
  2205.               EditorDialog (edReplaceNotPossible, nil)
  2206.             else
  2207.  
  2208.             { WRAP - Stop. }
  2209.  
  2210.               begin
  2211.  
  2212.                 Lock;
  2213.  
  2214.                 { MARK - Start. }
  2215.  
  2216.                 Search_Replace := True;
  2217.  
  2218.                 if length (ReplaceStr) < length (FindStr) then
  2219.                   Update_Place_Markers (0,
  2220.                                         Length (FindStr) - Length (ReplaceStr),
  2221.                                         CurPtr - Length (FindStr) + Length (ReplaceStr),
  2222.                                         CurPtr)
  2223.                 else
  2224.                   if length (ReplaceStr) > length (FindStr) then
  2225.                     Update_Place_Markers (Length (ReplaceStr) - Length (FindStr),
  2226.                                           0,
  2227.                                           CurPtr,
  2228.                                           CurPtr + (Length (ReplaceStr) - Length (FindStr)));
  2229.  
  2230.                 { MARK - Stop. }
  2231.  
  2232.                 InsertText (@ReplaceStr[1], Length (ReplaceStr), False);
  2233.  
  2234.                 { MARK - Start. }
  2235.  
  2236.                 Search_Replace := False;
  2237.  
  2238.                 { MARK - Stop. }
  2239.  
  2240.                 TrackCursor (False);
  2241.                 Unlock;
  2242.  
  2243.              end;
  2244.           end;
  2245.       end;
  2246.  
  2247.   until (I = Views.cmCancel) or (EditorFlags and efReplaceAll = 0);
  2248.  
  2249.  
  2250. end; { TEditor.DoSearchReplace }
  2251.  
  2252.  
  2253.  
  2254. { -------------------------------------------------------------------------- }
  2255.  
  2256.  
  2257.  
  2258. procedure TEditor.DoUpdate;
  2259.  
  2260. begin
  2261.  
  2262.   if UpdateFlags <> 0 then
  2263.   begin
  2264.  
  2265.     SetCursor (CurPos.X - Delta.X, CurPos.Y - Delta.Y);
  2266.  
  2267.     if UpdateFlags and ufView <> 0 then
  2268.       DrawView
  2269.     else
  2270.       if UpdateFlags and ufLine <> 0 then
  2271.         DrawLines (CurPos.Y - Delta.Y, 1, LineStart (CurPtr));
  2272.  
  2273.     if HScrollBar <> nil then
  2274.       HScrollBar^.SetParams (Delta.X, 0, Limit.X - Size.X, Size.X div 2, 1);
  2275.  
  2276.     if VScrollBar <> nil then
  2277.       VScrollBar^.SetParams (Delta.Y, 0, Limit.Y - Size.Y, Size.Y - 1, 1);
  2278.  
  2279.     { STATS - Start. }
  2280.  
  2281.     if Indicator <> nil then
  2282.       Indicator^.SetValue (CurPos, AutoIndent, Modified, Word_Wrap);
  2283.  
  2284.     { STATS - Stop. } { Added AutoIndent and Word_Wrap parameters. }
  2285.  
  2286.     if State and sfActive <> 0 then
  2287.       UpdateCommands;
  2288.  
  2289.     UpdateFlags := 0;
  2290.  
  2291.   end;
  2292.  
  2293.  
  2294. end; { TEditor.DoUpdate }
  2295.  
  2296.  
  2297.  
  2298. { -------------------------------------------------------------------------- }
  2299.  
  2300.  
  2301.  
  2302. { WRAP - Start. }
  2303.  
  2304. function TEditor.Do_Word_Wrap (Select_Mode   : Byte;
  2305.                                Center_Cursor : Boolean) : Boolean;
  2306.  
  2307.  
  2308.  
  2309.   { ---------------------------------------------------------------------- }
  2310.   {                                                                        }
  2311.   { This procedure does the actual wordwrap.  It always assumes the CurPtr }
  2312.   { is at Right_Margin + 1.  It makes several tests for special conditions }
  2313.   { and processes those first.  If they all fail, it does a normal wrap.   }
  2314.   {                                                                        }
  2315.   { ---------------------------------------------------------------------- }
  2316.  
  2317.  
  2318. VAR
  2319.  
  2320.   A : Word;          { Distance between line start and first word on line. }
  2321.   C : Word;          { Current pointer when we come into procedure.        }
  2322.   L : Word;          { BufLen when we come into procedure.                 }
  2323.   P : Word;          { Position of pointer at any given moment.            }
  2324.   S : Word;          { Start of a line.                                    }
  2325.  
  2326. begin
  2327.  
  2328.   Do_Word_Wrap := False;
  2329.   Select_Mode := 0;
  2330.  
  2331.   C := CurPtr;
  2332.   L := BufLen;
  2333.   S := LineStart (CurPtr);
  2334.  
  2335.  
  2336.  
  2337.   { -------------------------------------------------------------------- }
  2338.   {                                                                      }
  2339.   { If first character in the line is a space and autoindent mode is on  }
  2340.   { then we check to see if NextWord(S) exceeds the CurPtr.  If it does, }
  2341.   { we set CurPtr as the AutoIndent marker.  If it doesn't, we will set  }
  2342.   { NextWord(S) as the AutoIndent marker.  If neither, we set it to S.   }
  2343.   {                                                                      }
  2344.   { -------------------------------------------------------------------- }
  2345.  
  2346.  
  2347.   if AutoIndent and (Buffer^[S] = ' ') then
  2348.     begin
  2349.       if NextWord (S) > CurPtr then
  2350.         A := CurPtr
  2351.       else
  2352.         A := NextWord (S);
  2353.     end
  2354.   else
  2355.     A := NextWord (S);
  2356.  
  2357.  
  2358.  
  2359.   { --------------------------------------------------------- }
  2360.   {                                                           }
  2361.   { Though NewLine will remove EOL spaces, we do it here too. }
  2362.   { This catches the instance where a user may try to space   }
  2363.   { completely across the line, in which case CurPtr.X = 0.   }
  2364.   {                                                           }
  2365.   { --------------------------------------------------------- }
  2366.  
  2367.  
  2368.   Remove_EOL_Spaces (Select_Mode);
  2369.  
  2370.   if CurPos.X = 0 then
  2371.     begin
  2372.       NewLine (Select_Mode);
  2373.       Do_Word_Wrap := True;
  2374.       Exit;
  2375.     end;
  2376.  
  2377.  
  2378.  
  2379.   { --------------------------------------------------------------------------- }
  2380.   {                                                                             }
  2381.   { At this point we have one of five situations:                               }
  2382.   {                                                                             }
  2383.   { 1)  AutoIndent is on and this line is all spaces before CurPtr.             }
  2384.   { 2)  AutoIndent is off and this line is all spaces before CurPtr.            }
  2385.   { 3)  AutoIndent is on and this line is continuous characters before CurPtr.  }
  2386.   { 4)  AutoIndent is off and this line is continuous characters before CurPtr. }
  2387.   { 5)  This is just a normal line of text.                                     }
  2388.   {                                                                             }
  2389.   { Conditions 1 through 4 have to be taken into account before condition 5.    }
  2390.   {                                                                             }
  2391.   { --------------------------------------------------------------------------- }
  2392.  
  2393.  
  2394.  
  2395.   { ------------------------------------------------------------ }
  2396.   {                                                              }
  2397.   { First, we see if there are all spaces and/or all characters. }
  2398.   { Then we determine which one it really is.  Finally, we take  }
  2399.   { a course of action based on the state of AutoIndent.         }
  2400.   {                                                              }
  2401.   { ------------------------------------------------------------ }
  2402.  
  2403.  
  2404.  
  2405.   if PrevWord (CurPtr) <= S then
  2406.     begin
  2407.  
  2408.       P := CurPtr - 1;
  2409.  
  2410.       while ((Buffer^[P] <> ' ') and (P > S)) do
  2411.         Dec (P);
  2412.  
  2413.  
  2414.  
  2415.       { -------------------------------------------------------------- }
  2416.       {                                                                }
  2417.       { We found NO SPACES.  Conditions 4 and 5 are treated the same.  }
  2418.       { We can NOT do word wrap and put up a dialog box stating such.  }
  2419.       { Delete character just entered so we don't exceed Right_Margin. }
  2420.       {                                                                }
  2421.       { -------------------------------------------------------------- }
  2422.  
  2423.  
  2424.       if P = S then
  2425.         begin
  2426.           EditorDialog (edWrapNotPossible, nil);
  2427.           DeleteRange (PrevChar (CurPtr), CurPtr, True);
  2428.           Exit;
  2429.         end
  2430.       else
  2431.         begin
  2432.  
  2433.  
  2434.  
  2435.           { ------------------------------------------------------- }
  2436.           {                                                         }
  2437.           { There are spaces.  Now find out if they are all spaces. }
  2438.           { If so, see if AutoIndent is on.  If it is, turn it off, }
  2439.           { do a NewLine, and turn it back on.  Otherwise, just do  }
  2440.           { the NewLine.  We go through all of these gyrations for  }
  2441.           { AutoIndent.  Being way out here with a preceding line   }
  2442.           { of spaces and wrapping with AutoIndent on is real dumb! }
  2443.           { However, the user expects something.  The wrap will NOT }
  2444.           { autoindent, but they had no business being here anyway! }
  2445.           {                                                         }
  2446.           { ------------------------------------------------------- }
  2447.  
  2448.  
  2449.           P := CurPtr - 1;
  2450.  
  2451.           while ((Buffer^[P] = ' ') and (P > S)) do
  2452.             Dec (P);
  2453.  
  2454.           if P = S then
  2455.             begin
  2456.  
  2457.               if Autoindent then
  2458.                 begin
  2459.                   AutoIndent := False;
  2460.                   NewLine (Select_Mode);
  2461.                   AutoIndent := True;
  2462.                 end
  2463.               else
  2464.                 NewLine (Select_Mode);
  2465.               end; { AutoIndent }
  2466.  
  2467.             end; { P = S for spaces }
  2468.  
  2469.         end { P = S for no spaces }
  2470.  
  2471.     else { PrevWord (CurPtr) <= S }
  2472.  
  2473.       begin
  2474.  
  2475.  
  2476.         { ---------------------------------------------------------------- }
  2477.         {                                                                  }
  2478.         { Hooray!  We actually had a plain old line of text to wrap!       }
  2479.         { Regardless if we are pushing out a line beyond the Right_Margin, }
  2480.         { or at the end of a line itself, the following will determine     }
  2481.         { exactly where to do the wrap and re-set the cursor accordingly.  }
  2482.         { However, if P = A then we can't wrap.  Show dialog and exit.     }
  2483.         {                                                                  }
  2484.         { ---------------------------------------------------------------- }
  2485.  
  2486.  
  2487.         P := CurPtr;
  2488.  
  2489.         while P - S > Right_Margin do
  2490.           P := PrevWord (P);
  2491.  
  2492.         if (P = A) then
  2493.           begin
  2494.             EditorDialog (edReformNotPossible, nil);
  2495.             SetCurPtr (P, Select_Mode);
  2496.             Exit;
  2497.           end;
  2498.  
  2499.         SetCurPtr (P, Select_Mode);
  2500.         NewLine (Select_Mode);
  2501.  
  2502.     end; { PrevWord (CurPtr <= S }
  2503.  
  2504.  
  2505.  
  2506.   { ---------------------------------------------------------- }
  2507.   {                                                            }
  2508.   { Track the cursor here (it is at CurPos.X = 0) so the view  }
  2509.   { will redraw itself at column 0.  This eliminates having it }
  2510.   { redraw starting at the current cursor and not being able   }
  2511.   { to see text before the cursor.  Of course, we also end up  }
  2512.   { redrawing the view twice, here and back in HandleEvent.    }
  2513.   {                                                            }
  2514.   { Reposition cursor so user can pick up where they left off. }
  2515.   {                                                            }
  2516.   { ---------------------------------------------------------- }
  2517.  
  2518.  
  2519.   TrackCursor (Center_Cursor);
  2520.   SetCurPtr (C - (L - BufLen), Select_Mode);
  2521.  
  2522.   Do_Word_Wrap := True;
  2523.  
  2524.  
  2525. end; { TEditor.Do_Word_Wrap }
  2526.  
  2527. { WRAP - Stop. }
  2528.  
  2529.  
  2530.  
  2531. { -------------------------------------------------------------------------- }
  2532.  
  2533.  
  2534.  
  2535. procedure TEditor.Draw;
  2536.  
  2537. begin
  2538.  
  2539.   if DrawLine <> Delta.Y then
  2540.   begin
  2541.     DrawPtr := LineMove (DrawPtr, Delta.Y - DrawLine);
  2542.     DrawLine := Delta.Y;
  2543.   end;
  2544.  
  2545.   DrawLines (0, Size.Y, DrawPtr);
  2546.  
  2547.  
  2548. end; { TEditor.Draw }
  2549.  
  2550.  
  2551.  
  2552. { -------------------------------------------------------------------------- }
  2553.  
  2554.  
  2555.  
  2556. procedure TEditor.DrawLines (Y, Count : Integer; LinePtr : Word);
  2557.  
  2558. VAR
  2559.  
  2560.   Color : Word;
  2561.   B     : array[0..MaxLineLength - 1] of Word;
  2562.  
  2563. begin
  2564.  
  2565.   Color := GetColor ($0201);
  2566.  
  2567.   while Count > 0 do
  2568.   begin
  2569.     FormatLine (B, LinePtr, Delta.X + Size.X, Color);
  2570.     WriteBuf (0, Y, Size.X, 1, B[Delta.X]);
  2571.     LinePtr := NextLine (LinePtr);
  2572.     Inc (Y);
  2573.     Dec (Count);
  2574.   end;
  2575.  
  2576.  
  2577. end; { TEditor.DrawLines }
  2578.  
  2579.  
  2580.  
  2581. { -------------------------------------------------------------------------- }
  2582.  
  2583.  
  2584.  
  2585. procedure TEditor.Find;
  2586.  
  2587. VAR
  2588.  
  2589.   FindRec : TFindDialogRec;
  2590.  
  2591. begin
  2592.  
  2593.   with FindRec do
  2594.   begin
  2595.  
  2596.     Find := FindStr;
  2597.     Options := EditorFlags;
  2598.  
  2599.     if EditorDialog (edFind, @FindRec) <> Views.cmCancel then
  2600.     begin
  2601.       FindStr := Find;
  2602.       EditorFlags := Options and not efDoReplace;
  2603.       DoSearchReplace;
  2604.     end;
  2605.  
  2606.   end;
  2607.  
  2608.  
  2609. end; { TEditor.Find }
  2610.  
  2611.  
  2612.  
  2613. { -------------------------------------------------------------------------- }
  2614.  
  2615.  
  2616.  
  2617. procedure TEditor.FormatLine (var DrawBuf; LinePtr : Word;
  2618.                                   Width  : Integer;
  2619.                                   Colors : Word); assembler;
  2620.  
  2621. asm
  2622.         PUSH    DS
  2623.         LDS     BX,Self
  2624.         LES     DI,DrawBuf
  2625.         MOV     SI,LinePtr
  2626.         XOR     DX,DX
  2627.         CLD
  2628.         MOV     AH,Colors.Byte[0]
  2629.         MOV     CX,DS:[BX].TEditor.SelStart
  2630.         CALL    @@10
  2631.         MOV     AH,Colors.Byte[1]
  2632.         MOV     CX,DS:[BX].TEditor.CurPtr
  2633.         CALL    @@10
  2634.         ADD     SI,DS:[BX].TEditor.GapLen
  2635.         MOV     CX,DS:[BX].TEditor.SelEnd
  2636.         ADD     CX,DS:[BX].TEditor.GapLen
  2637.         CALL    @@10
  2638.         MOV     AH,Colors.Byte[0]
  2639.         MOV     CX,DS:[BX].TEditor.BufSize
  2640.         CALL    @@10
  2641.         JMP     @@31
  2642. @@10:   SUB     CX,SI
  2643.         JA      @@11
  2644.         RETN
  2645. @@11:   LDS     BX,DS:[BX].TEditor.Buffer
  2646.         ADD     SI,BX
  2647.         MOV     BX,Width
  2648. @@12:   LODSB
  2649.         CMP     AL,' '
  2650.         JB      @@20
  2651. @@13:   STOSW
  2652.         INC     DX
  2653. @@14:   CMP     DX,BX
  2654.         JAE     @@30
  2655.         LOOP    @@12
  2656.         LDS     BX,Self
  2657.         SUB     SI,DS:[BX].TEditor.Buffer.Word[0]
  2658.         RETN
  2659. @@20:   CMP     AL,0DH
  2660.         JE      @@30
  2661.         CMP     AL,09H
  2662.         JNE     @@13
  2663.         MOV     AL,' '
  2664. @@21:   STOSW
  2665.         INC     DX
  2666.         TEST    DL,7
  2667.         JNE     @@21
  2668.         JMP     @@14
  2669. @@30:   POP     CX
  2670. @@31:   MOV     AL,' '
  2671.         MOV     CX,Width
  2672.         SUB     CX,DX
  2673.         JBE     @@32
  2674.         REP     STOSW
  2675. @@32:   POP     DS
  2676.  
  2677.  
  2678. end; {TEditor.FormatLine}
  2679.  
  2680.  
  2681.  
  2682. { -------------------------------------------------------------------------- }
  2683.  
  2684.  
  2685.  
  2686. function TEditor.GetMousePtr (Mouse : Objects.TPoint) : Word;
  2687.  
  2688. begin
  2689.  
  2690.   MakeLocal (Mouse, Mouse);
  2691.   Mouse.X := Max (0, Min (Mouse.X, Size.X - 1));
  2692.   Mouse.Y := Max (0, Min (Mouse.Y, Size.Y - 1));
  2693.  
  2694.   GetMousePtr := CharPtr (LineMove (DrawPtr, Mouse.Y + Delta.Y - DrawLine),
  2695.                           Mouse.X + Delta.X);
  2696.  
  2697.  
  2698. end; { TEditor.GetMousePtr }
  2699.  
  2700.  
  2701.  
  2702. { -------------------------------------------------------------------------- }
  2703.  
  2704.  
  2705.  
  2706. function TEditor.GetPalette : Views.PPalette;
  2707.  
  2708. CONST
  2709.  
  2710.   P : String[Length (CEditor)] = CEditor;
  2711.  
  2712. begin
  2713.  
  2714.   GetPalette := @P;
  2715.  
  2716.  
  2717. end; { TEditor.GetPalette }
  2718.  
  2719.  
  2720.  
  2721. { -------------------------------------------------------------------------- }
  2722.  
  2723.  
  2724.  
  2725. procedure TEditor.HandleEvent (var Event : Drivers.TEvent);
  2726.  
  2727. VAR
  2728.  
  2729.   ShiftState   : Byte absolute $40:$17;
  2730.   CenterCursor : Boolean;
  2731.   SelectMode   : Byte;
  2732.   I            : Integer;
  2733.   D            : Objects.TPoint;
  2734.   Mouse        : Objects.TPoint;
  2735.  
  2736.  
  2737.  
  2738.   { ------------------------------------------------------------------------ }
  2739.  
  2740.  
  2741.  
  2742.   { SCRLBG - Start }
  2743.  
  2744.   { procedure CheckScrollBar (P : PScrollBar; var D : Integer); }
  2745.   function CheckScrollBar (P : PScrollBar; var D : Integer) : Boolean;
  2746.  
  2747.   { SCRLBG - Stop. } { Changed froma procedure to a function. }
  2748.  
  2749.   begin
  2750.  
  2751.     { SCRLBG - Start. }
  2752.  
  2753.     CheckScrollBar := FALSE;
  2754.  
  2755.     { SCRLBG - Stop. } { Set function return to default to FALSE. }
  2756.  
  2757.     if (Event.InfoPtr = P) and (P^.Value <> D) then
  2758.     begin
  2759.       D := P^.Value;
  2760.       Update (ufView);
  2761.  
  2762.       { SCRLBG - Start. }
  2763.  
  2764.       CheckScrollBar := TRUE;
  2765.  
  2766.       { SCRLBG - Stop. } { Set function return to TRUE. }
  2767.  
  2768.     end;
  2769.  
  2770.  
  2771.   end; {CheckScrollBar}
  2772.  
  2773.  
  2774.  
  2775.   { ------------------------------------------------------------------------ }
  2776.  
  2777.  
  2778.  
  2779. begin
  2780.  
  2781.   TView.HandleEvent (Event);
  2782.   ConvertEvent (Event);
  2783.   CenterCursor := not CursorVisible;
  2784.   SelectMode := 0;
  2785.  
  2786.   if Selecting or (ShiftState and $03 <> 0) then
  2787.     SelectMode := smExtend;
  2788.  
  2789.   case Event.What of
  2790.  
  2791.     Drivers.evMouseDown:
  2792.  
  2793.       begin
  2794.         if Event.Double then
  2795.           SelectMode := SelectMode or smDouble;
  2796.  
  2797.         repeat
  2798.           Lock;
  2799.  
  2800.           if Event.What = evMouseAuto then
  2801.           begin
  2802.             MakeLocal (Event.Where, Mouse);
  2803.             D := Delta;
  2804.             if Mouse.X < 0 then
  2805.               Dec (D.X);
  2806.             if Mouse.X >= Size.X then
  2807.               Inc (D.X);
  2808.             if Mouse.Y < 0 then
  2809.               Dec (D.Y);
  2810.             if Mouse.Y >= Size.Y then
  2811.               Inc (D.Y);
  2812.             ScrollTo (D.X, D.Y);
  2813.           end;
  2814.  
  2815.           SetCurPtr (GetMousePtr (Event.Where), SelectMode);
  2816.           SelectMode := SelectMode or smExtend;
  2817.           Unlock;
  2818.  
  2819.         until not MouseEvent (Event, evMouseMove + evMouseAuto);
  2820.  
  2821.       end; { Drivers.evMouseDown }
  2822.  
  2823.     Drivers.evKeyDown:
  2824.  
  2825.       case Event.CharCode of
  2826.  
  2827.         #32..#255:
  2828.  
  2829.           begin
  2830.             Lock;
  2831.  
  2832.             if Overwrite and not HasSelection then
  2833.               if CurPtr <> LineEnd (CurPtr) then
  2834.                 SelEnd := NextChar (CurPtr);
  2835.  
  2836.             InsertText (@Event.CharCode, 1, False);
  2837.  
  2838.             { WRAP - Start. }
  2839.  
  2840.             if Word_Wrap then
  2841.               Check_For_Word_Wrap (SelectMode, CenterCursor);
  2842.  
  2843.             { WRAP - Stop. } { Added code to check for wordwrap. }
  2844.  
  2845.             TrackCursor (CenterCursor);
  2846.             Unlock;
  2847.  
  2848.           end;
  2849.  
  2850.       else
  2851.  
  2852.         Exit;
  2853.  
  2854.       end; { Drivers.evKeyDown }
  2855.  
  2856.     Drivers.evCommand:
  2857.  
  2858.       case Event.Command of
  2859.  
  2860.         cmFind        : Find;
  2861.         cmReplace     : Replace;
  2862.         cmSearchAgain : DoSearchReplace;
  2863.  
  2864.       else
  2865.  
  2866.         begin
  2867.  
  2868.           Lock;
  2869.  
  2870.           case Event.Command of
  2871.  
  2872.             cmCut         : ClipCut;
  2873.             cmCopy        : ClipCopy;
  2874.             cmPaste       : ClipPaste;
  2875.             cmUndo        : Undo;
  2876.             cmClear       : DeleteSelect;
  2877.             cmCharLeft    : SetCurPtr (PrevChar  (CurPtr), SelectMode);
  2878.             cmCharRight   : SetCurPtr (NextChar  (CurPtr), SelectMode);
  2879.             cmWordLeft    : SetCurPtr (PrevWord  (CurPtr), SelectMode);
  2880.             cmWordRight   : SetCurPtr (NextWord  (CurPtr), SelectMode);
  2881.             cmLineStart   : SetCurPtr (LineStart (CurPtr), SelectMode);
  2882.             cmLineEnd     : SetCurPtr (LineEnd   (CurPtr), SelectMode);
  2883.             cmLineUp      : SetCurPtr (LineMove  (CurPtr, -1), SelectMode);
  2884.             cmLineDown    : SetCurPtr (LineMove  (CurPtr, 1),  SelectMode);
  2885.             cmPageUp      : SetCurPtr (LineMove  (CurPtr, - (Size.Y - 1)), SelectMode);
  2886.             cmPageDown    : SetCurPtr (LineMove  (CurPtr, Size.Y - 1), SelectMode);
  2887.             cmTextStart   : SetCurPtr (0, SelectMode);
  2888.             cmTextEnd     : SetCurPtr (BufLen, SelectMode);
  2889.  
  2890.             { WRAP - Start. }
  2891.  
  2892.             cmNewLine     : NewLine (SelectMode);
  2893.  
  2894.             { WRAP - Stop. } { Add new parameter to call. }
  2895.  
  2896.             cmBackSpace   : DeleteRange (PrevChar (CurPtr), CurPtr, True);
  2897.             cmDelChar     : DeleteRange (CurPtr, NextChar (CurPtr), True);
  2898.             cmDelWord     : DeleteRange (CurPtr, NextWord (CurPtr), False);
  2899.             cmDelStart    : DeleteRange (LineStart (CurPtr), CurPtr, False);
  2900.             cmDelEnd      : DeleteRange (CurPtr, LineEnd (CurPtr), False);
  2901.             cmDelLine     : DeleteRange (LineStart (CurPtr), NextLine (CurPtr), False);
  2902.             cmInsMode     : ToggleInsMode;
  2903.             cmStartSelect : StartSelect;
  2904.             cmHideSelect  : HideSelect;
  2905.  
  2906.             { STATS - Start. }
  2907.  
  2908.             cmIndentMode  : begin
  2909.                               AutoIndent := not AutoIndent;
  2910.                               Update (ufStats);
  2911.                             end; { Added provision to update TIndicator if ^QI pressed. }
  2912.  
  2913.             { STATS - Stop. }
  2914.  
  2915.             { CENTER - Start. }
  2916.             { HOMEND - Start. }
  2917.             { INSLIN - Start. }
  2918.             { JLINE  - Start. }
  2919.             { MARK   - Start. }
  2920.             { PRETAB - Start. }
  2921.             { REFDOC - Start. }
  2922.             { REFORM - Start. }
  2923.             { RMSET  - Start. }
  2924.             { SCRLDN - Start. }
  2925.             { SCRLUP - Start. }
  2926.             { SELWRD - Start. }
  2927.             { WRAP   - Start. }
  2928.  
  2929.             cmCenterText  : Center_Text (SelectMode);
  2930.             cmEndPage     : SetCurPtr (LineMove  (CurPtr, Delta.Y - CurPos.Y + Size.Y - 1), SelectMode);
  2931.             cmHomePage    : SetCurPtr (LineMove  (CurPtr, -(CurPos.Y - Delta.Y)), SelectMode);
  2932.             cmInsertLine  : Insert_Line (SelectMode);
  2933.             cmJumpLine    : Jump_To_Line (SelectMode);
  2934.             cmReformDoc   : Reformat_Document (SelectMode, CenterCursor);
  2935.             cmReformPara  : Reformat_Paragraph (SelectMode, CenterCursor);
  2936.             cmRightMargin : Set_Right_Margin;
  2937.             cmScrollDown  : Scroll_Down;
  2938.             cmScrollUp    : Scroll_Up;
  2939.             cmSelectWord  : Select_Word;
  2940.             cmSetTabs     : Set_Tabs;
  2941.             cmTabKey      : Tab_Key (SelectMode);
  2942.  
  2943.             { STATS  - Start. }
  2944.  
  2945.             cmWordWrap    : begin
  2946.                               Word_Wrap := not Word_Wrap;
  2947.                               Update (ufStats);
  2948.                             end; { Added provision to update TIndicator if ^OW pressed. }
  2949.  
  2950.             { STATS  - Stop. }
  2951.  
  2952.             cmSetMark0    : Set_Place_Marker (10);
  2953.             cmSetMark1    : Set_Place_Marker  (1);
  2954.             cmSetMark2    : Set_Place_Marker  (2);
  2955.             cmSetMark3    : Set_Place_Marker  (3);
  2956.             cmSetMark4    : Set_Place_Marker  (4);
  2957.             cmSetMark5    : Set_Place_Marker  (5);
  2958.             cmSetMark6    : Set_Place_Marker  (6);
  2959.             cmSetMark7    : Set_Place_Marker  (7);
  2960.             cmSetMark8    : Set_Place_Marker  (8);
  2961.             cmSetMark9    : Set_Place_Marker  (9);
  2962.  
  2963.             cmJumpMark0   : Jump_Place_Marker (10, SelectMode);
  2964.             cmJumpMark1   : Jump_Place_Marker  (1, SelectMode);
  2965.             cmJumpMark2   : Jump_Place_Marker  (2, SelectMode);
  2966.             cmJumpMark3   : Jump_Place_Marker  (3, SelectMode);
  2967.             cmJumpMark4   : Jump_Place_Marker  (4, SelectMode);
  2968.             cmJumpMark5   : Jump_Place_Marker  (5, SelectMode);
  2969.             cmJumpMark6   : Jump_Place_Marker  (6, SelectMode);
  2970.             cmJumpMark7   : Jump_Place_Marker  (7, SelectMode);
  2971.             cmJumpMark8   : Jump_Place_Marker  (8, SelectMode);
  2972.             cmJumpMark9   : Jump_Place_Marker  (9, SelectMode);
  2973.  
  2974.             { WRAP   - Stop. } { Added cmWordWrap event.                  }
  2975.             { SELWRD - Stop. } { Added cmSelectWord event.                }
  2976.             { SCRLUP - Stop. } { Added cmScrollUp event.                  }
  2977.             { SCRLDN - Stop. } { Added cmScrollDown event.                }
  2978.             { RMSET  - Stop. } { Added cmRightMargin event.               }
  2979.             { REFORM - Stop. } { Added cmReformPara event.                }
  2980.             { REFDOC - Stop. } { Added cmReformDoc event.                 }
  2981.             { PRETAB - Stop. } { Added cmTabKey event.                    }
  2982.             { MARK   - Stop. } { Added cmSetMark# and cmJumpMark# events. }
  2983.             { JLINE  - Stop. } { Added cmJumpLine event.                  }
  2984.             { INSLIN - Stop. } { Added cmInsertLine event.                }
  2985.             { HOMEND - Stop. } { Added cmHomePage and cmEndPage events.   }
  2986.             { CENTER - Stop. { { Added cmCenterText event.                }
  2987.  
  2988.           else
  2989.  
  2990.             Unlock;
  2991.             Exit;
  2992.  
  2993.           end; { Event.Command (Inner) }
  2994.  
  2995.           TrackCursor (CenterCursor);
  2996.  
  2997.           { WRAP - Start. }
  2998.  
  2999.           { ------------------------------------------------------------ }
  3000.           {                                                              }
  3001.           { If the user presses any key except cmNewline or cmBackspace  }
  3002.           { we need to check if the file has been modified yet.  There   }
  3003.           { can be no spaces at the end of a line, or wordwrap doesn't   }
  3004.           { work properly.  We don't want to do this if the file hasn't  }
  3005.           { been modified because the user could be bringing in an ASCII }
  3006.           { file from an editor that allows spaces at the EOL.  If we    }
  3007.           { took them out in that scenario the "M" would appear on the   }
  3008.           { TIndicator line and the user would get upset or confused.    }
  3009.           {                                                              }
  3010.           { ------------------------------------------------------------ }
  3011.  
  3012.  
  3013.           if (Event.Command <> cmNewLine)   and
  3014.              (Event.Command <> cmBackSpace) and
  3015.              (Event.Command <> cmTabKey)    and
  3016.               Modified then
  3017.             Remove_EOL_Spaces (SelectMode);
  3018.  
  3019.           { WRAP - Stop. } { Added code to check for wordwrap, and to  }
  3020.                            { ignore removing EOL spaces for cmNewLine. }
  3021.  
  3022.           Unlock;
  3023.  
  3024.         end; { Event.Command (Outer) }
  3025.  
  3026.       end; { Drivers.evCommand }
  3027.  
  3028.     Drivers.evBroadcast:
  3029.  
  3030.       case Event.Command of
  3031.         cmScrollBarChanged:
  3032.           begin
  3033.  
  3034.             { SCRLBG - Start. }
  3035.  
  3036.             { ------------------------------------------------------------ }
  3037.             {                                                              }
  3038.             { The problem with this bug was that it would clear the event. }
  3039.             { Don't allow the event to be cleared if the sending scrollbar }
  3040.             { is not the scrollbar in question.                            }
  3041.             {                                                              }
  3042.             { ------------------------------------------------------------ }
  3043.  
  3044.             { CheckScrollBar (HScrollBar, Delta.X); }
  3045.             { CheckScrollBar (VScrollBar, Delta.Y); }
  3046.  
  3047.             if NOT (CheckScrollBar (HScrollBar, Delta.X)
  3048.                 OR  CheckScrollBar (VScrollBar, Delta.Y)) then
  3049.               Exit;
  3050.  
  3051.           end;
  3052.       else
  3053.  
  3054.         Exit;
  3055.  
  3056.       end; { Drivers.evBroadcast }
  3057.  
  3058.   end;
  3059.  
  3060.   ClearEvent (Event);
  3061.  
  3062.  
  3063. end; { TEditor.HandleEvent }
  3064.  
  3065.  
  3066.  
  3067. { -------------------------------------------------------------------------- }
  3068.  
  3069.  
  3070.  
  3071. function TEditor.HasSelection : Boolean;
  3072.  
  3073. begin
  3074.  
  3075.   HasSelection := SelStart <> SelEnd;
  3076.  
  3077.  
  3078. end; { TEditor.HasSelection }
  3079.  
  3080.  
  3081.  
  3082. { -------------------------------------------------------------------------- }
  3083.  
  3084.  
  3085.  
  3086. procedure TEditor.HideSelect;
  3087.  
  3088. begin
  3089.  
  3090.   Selecting := False;
  3091.   SetSelect (CurPtr, CurPtr, False);
  3092.  
  3093.  
  3094. end; { TEditor.HideSelect }
  3095.  
  3096.  
  3097.  
  3098. { -------------------------------------------------------------------------- }
  3099.  
  3100.  
  3101.  
  3102. procedure TEditor.InitBuffer;
  3103.  
  3104. begin
  3105.  
  3106.   Buffer := MemAlloc (BufSize);
  3107.  
  3108.  
  3109. end; { TEditor.InitBuffer }
  3110.  
  3111.  
  3112.  
  3113. { -------------------------------------------------------------------------- }
  3114.  
  3115.  
  3116.  
  3117. function TEditor.InsertBuffer (var P : PEditBuffer;
  3118.                                Offset,    Length     : Word;
  3119.                                AllowUndo, SelectText : Boolean) : Boolean;
  3120.  
  3121. VAR
  3122.  
  3123.   SelLen   : Word;
  3124.   DelLen   : Word;
  3125.   SelLines : Word;
  3126.   Lines    : Word;
  3127.   NewSize  : Longint;
  3128.  
  3129. begin
  3130.  
  3131.   InsertBuffer := True;
  3132.   Selecting := False;
  3133.  
  3134.   SelLen := SelEnd - SelStart;
  3135.  
  3136.   if (SelLen = 0) and (Length = 0) then
  3137.     Exit;
  3138.  
  3139.   DelLen := 0;
  3140.  
  3141.   if AllowUndo then
  3142.     if CurPtr = SelStart then
  3143.       DelLen := SelLen
  3144.     else
  3145.       if SelLen > InsCount then
  3146.         DelLen := SelLen - InsCount;
  3147.  
  3148.   NewSize := Longint (BufLen + DelCount - SelLen + DelLen) + Length;
  3149.  
  3150.   if NewSize > BufLen + DelCount then
  3151.     if (NewSize > $FFF0) or not SetBufSize (NewSize) then
  3152.       begin
  3153.         EditorDialog (edOutOfMemory, nil);
  3154.         InsertBuffer := False;
  3155.         Exit;
  3156.       end;
  3157.  
  3158.   SelLines := CountLines (Buffer^[BufPtr (SelStart)], SelLen);
  3159.  
  3160.   if CurPtr = SelEnd then
  3161.   begin
  3162.  
  3163.     if AllowUndo then
  3164.     begin
  3165.       if DelLen > 0 then
  3166.         Move (Buffer^[SelStart], Buffer^[CurPtr + GapLen - DelCount - DelLen], DelLen);
  3167.       Dec (InsCount, SelLen - DelLen);
  3168.     end;
  3169.  
  3170.     CurPtr := SelStart;
  3171.     Dec (CurPos.Y, SelLines);
  3172.  
  3173.   end;
  3174.  
  3175.   if Delta.Y > CurPos.Y then
  3176.     begin
  3177.       Dec (Delta.Y, SelLines);
  3178.       if Delta.Y < CurPos.Y then
  3179.         Delta.Y := CurPos.Y;
  3180.     end;
  3181.  
  3182.   if Length > 0 then
  3183.     Move (P^[Offset], Buffer^[CurPtr], Length);
  3184.  
  3185.   Lines := CountLines (Buffer^[CurPtr], Length);
  3186.  
  3187.   Inc (CurPtr, Length);
  3188.   Inc (CurPos.Y, Lines);
  3189.  
  3190.   DrawLine := CurPos.Y;
  3191.   DrawPtr := LineStart (CurPtr);
  3192.  
  3193.   CurPos.X := CharPos (DrawPtr, CurPtr);
  3194.  
  3195.   if not SelectText then
  3196.     SelStart := CurPtr;
  3197.  
  3198.   SelEnd := CurPtr;
  3199.  
  3200.   Inc (BufLen, Length - SelLen);
  3201.   Dec (GapLen, Length - SelLen);
  3202.  
  3203.   if AllowUndo then
  3204.     begin
  3205.       Inc (DelCount, DelLen);
  3206.       Inc (InsCount, Length);
  3207.     end;
  3208.  
  3209.   Inc (Limit.Y, Lines - SelLines);
  3210.   Delta.Y := Max (0, Min (Delta.Y, Limit.Y - Size.Y));
  3211.  
  3212.   if not IsClipboard then
  3213.     Modified := True;
  3214.  
  3215.   SetBufSize (BufLen + DelCount);
  3216.  
  3217.   if (SelLines = 0) and (Lines = 0) then
  3218.     Update (ufLine)
  3219.   else
  3220.     Update (ufView);
  3221.  
  3222.  
  3223. end; { TEditor.InsertBuffer }
  3224.  
  3225.  
  3226.  
  3227. { -------------------------------------------------------------------------- }
  3228.  
  3229.  
  3230.  
  3231. function TEditor.InsertFrom (Editor : PEditor) : Boolean;
  3232.  
  3233. begin
  3234.  
  3235.   InsertFrom := InsertBuffer (Editor^.Buffer,
  3236.     Editor^.BufPtr (Editor^.SelStart),
  3237.     Editor^.SelEnd - Editor^.SelStart, CanUndo, IsClipboard);
  3238.  
  3239.  
  3240. end; { TEditor.InsertFrom }
  3241.  
  3242.  
  3243.  
  3244. { -------------------------------------------------------------------------- }
  3245.  
  3246.  
  3247.  
  3248. { INSLIN - Start. }
  3249.  
  3250. procedure TEditor.Insert_Line (Select_Mode : Byte);
  3251.  
  3252.  
  3253.   { --------------------------------------------------------------- }
  3254.   {                                                                 }
  3255.   { This procedure inserts a newline at the current cursor position }
  3256.   { if a ^N is pressed.  Unlike cmNewLine, the cursor will return   }
  3257.   { to its original position.  If the cursor was at the end of a    }
  3258.   { line, and its spaces were removed, the cursor returns to the    }
  3259.   { end of the line instead.                                        }
  3260.   {                                                                 }
  3261.   { --------------------------------------------------------------- }
  3262.  
  3263.  
  3264.  
  3265. begin
  3266.  
  3267.   NewLine (Select_Mode);
  3268.   SetCurPtr (LineEnd (LineMove (CurPtr, -1)), Select_Mode);
  3269.  
  3270.  
  3271. end; { TEditor.Insert_Line }
  3272.  
  3273. { INSLIN - Stop. }
  3274.  
  3275.  
  3276.  
  3277. { -------------------------------------------------------------------------- }
  3278.  
  3279.  
  3280.  
  3281. function TEditor.InsertText (Text       : Pointer;
  3282.                              Length     : Word;
  3283.                              SelectText : Boolean) : Boolean;
  3284.  
  3285. begin
  3286.  
  3287.   { MARK - Start. }
  3288.  
  3289.   if (Text <> NIL) and not Search_Replace then
  3290.     Update_Place_Markers (Length, 0, Self.SelStart, Self.SelEnd);
  3291.  
  3292.   { MARK - Stop } { This will update Place_Marker ONLY if we are inserting text.}
  3293.                   { ClipPaste and deletions of any sort are handled elsewhere.  }
  3294.  
  3295.   InsertText := InsertBuffer (PEditBuffer (Text),
  3296.                 0, Length, CanUndo, SelectText);
  3297.  
  3298.  
  3299. end; { TEditor.InsertText }
  3300.  
  3301.  
  3302.  
  3303. { -------------------------------------------------------------------------- }
  3304.  
  3305.  
  3306.  
  3307. function TEditor.IsClipboard : Boolean;
  3308.  
  3309. begin
  3310.  
  3311.   IsClipboard := Clipboard = @Self;
  3312.  
  3313.  
  3314. end; { TEditor.IsClipboard }
  3315.  
  3316.  
  3317.  
  3318. { -------------------------------------------------------------------------- }
  3319.  
  3320.  
  3321.  
  3322. { MARK - Start. }
  3323.  
  3324. procedure TEditor.Jump_Place_Marker (Element : Byte; Select_Mode : Byte);
  3325.  
  3326.  
  3327.   { ---------------------------------------------------------- }
  3328.   {                                                            }
  3329.   { This procedure jumps to a place marker if ^Q# is pressed.  }
  3330.   { We don't go anywhere if Place_Marker[Element] is not zero. }
  3331.   {                                                            }
  3332.   { ---------------------------------------------------------- }
  3333.  
  3334.  
  3335. begin
  3336.  
  3337.   if (not IsClipboard) and (Place_Marker[Element] <> 0) then
  3338.     SetCurPtr (Place_Marker[Element], Select_Mode);
  3339.  
  3340.  
  3341. end; { TEditor.Jump_Place_Marker }
  3342.  
  3343. { MARK - Stop. }
  3344.  
  3345.  
  3346.  
  3347. { -------------------------------------------------------------------------- }
  3348.  
  3349.  
  3350.  
  3351. { JLINE - Start. }
  3352.  
  3353. procedure TEditor.Jump_To_Line (Select_Mode : Byte);
  3354.  
  3355.  
  3356.   { ------------------------------------------------ }
  3357.   {                                                  }
  3358.   { This function brings up a dialog box that allows }
  3359.   { the user to select a line number to jump to.     }
  3360.   {                                                  }
  3361.   { ------------------------------------------------ }
  3362.  
  3363.  
  3364. VAR
  3365.  
  3366.   Code       : Integer;         { Used for Val conversion.      }
  3367.   Temp_Value : Integer;         { Holds converted dialog value. }
  3368.  
  3369. begin
  3370.  
  3371.  
  3372.   if EditorDialog (edJumpToLine, @Line_Number) <> Views.cmCancel then
  3373.     begin
  3374.  
  3375.  
  3376.  
  3377.       { ---------------------------------------------- }
  3378.       {                                                }
  3379.       { Convert the Line_Number string to an interger. }
  3380.       { Put it into Temp_Value.  If the number is not  }
  3381.       { in the range 1..9999 abort.  If the number is  }
  3382.       { our current Y position, abort.  Otherwise,     }
  3383.       { go to top of document, and jump to the line.   }
  3384.       { There are faster methods.  This one's easy.    }
  3385.       { Note that CurPos.Y is always 1 less than what  }
  3386.       { the TIndicator line says.                      }
  3387.       {                                                }
  3388.       { ---------------------------------------------- }
  3389.  
  3390.  
  3391.       val (Line_Number, Temp_Value, Code);
  3392.  
  3393.       if (Temp_Value < 1) or (Temp_Value > 9999) then
  3394.         Exit;
  3395.  
  3396.       if Temp_Value = CurPos.Y + 1 then
  3397.         Exit;
  3398.  
  3399.       SetCurPtr (0, Select_Mode);
  3400.       SetCurPtr (LineMove (CurPtr, Temp_Value - 1), Select_Mode);
  3401.  
  3402.     end;
  3403.  
  3404.  
  3405. end; {TEditor.Jump_To_Line}
  3406.  
  3407. { JLINE - Stop. }
  3408.  
  3409.  
  3410.  
  3411. { -------------------------------------------------------------------------- }
  3412.  
  3413.  
  3414.  
  3415. function TEditor.LineEnd (P : Word) : Word; assembler;
  3416.  
  3417. asm
  3418.         PUSH    DS
  3419.         LDS     SI,Self
  3420.         LES     BX,DS:[SI].TEditor.Buffer
  3421.         MOV     DI,P
  3422.         MOV     AL,0DH
  3423.         CLD
  3424.         MOV     CX,DS:[SI].TEditor.CurPtr
  3425.         SUB     CX,DI
  3426.         JBE     @@1
  3427.         ADD     DI,BX
  3428.         REPNE   SCASB
  3429.         JE      @@2
  3430.         MOV     DI,DS:[SI].TEditor.CurPtr
  3431. @@1:    MOV     CX,DS:[SI].TEditor.BufLen
  3432.         SUB     CX,DI
  3433.         JCXZ    @@4
  3434.         ADD     BX,DS:[SI].TEditor.GapLen
  3435.         ADD     DI,BX
  3436.         REPNE   SCASB
  3437.         JNE     @@3
  3438. @@2:    DEC     DI
  3439. @@3:    SUB     DI,BX
  3440. @@4:    MOV     AX,DI
  3441.         POP     DS
  3442.  
  3443.  
  3444. end; { TEditor.LineEnd }
  3445.  
  3446.  
  3447.  
  3448. { -------------------------------------------------------------------------- }
  3449.  
  3450.  
  3451.  
  3452. function TEditor.LineMove (P : Word; Count : Integer) : Word;
  3453.  
  3454. VAR
  3455.  
  3456.   Pos : Integer;
  3457.   I   : Word;
  3458.  
  3459. begin
  3460.  
  3461.   I := P;
  3462.   P := LineStart (P);
  3463.   Pos := CharPos (P, I);
  3464.  
  3465.   while Count <> 0 do
  3466.   begin
  3467.     I := P;
  3468.     if Count < 0 then
  3469.       begin
  3470.         P := PrevLine (P);
  3471.         Inc (Count);
  3472.       end
  3473.     else
  3474.       begin
  3475.         P := NextLine (P);
  3476.         Dec (Count);
  3477.       end;
  3478.   end;
  3479.  
  3480.   if P <> I then
  3481.     P := CharPtr (P, Pos);
  3482.  
  3483.   LineMove := P;
  3484.  
  3485.  
  3486. end; { TEditor.LineMove }
  3487.  
  3488.  
  3489.  
  3490. { -------------------------------------------------------------------------- }
  3491.  
  3492.  
  3493.  
  3494. function TEditor.LineStart (P : Word) : Word; assembler;
  3495.  
  3496. asm
  3497.         PUSH    DS
  3498.         LDS     SI,Self
  3499.         LES     BX,DS:[SI].TEditor.Buffer
  3500.         MOV     DI,P
  3501.         MOV     AL,0DH
  3502.         STD
  3503.         MOV     CX,DI
  3504.         SUB     CX,DS:[SI].TEditor.CurPtr
  3505.         JBE     @@1
  3506.         ADD     BX,DS:[SI].TEditor.GapLen
  3507.         ADD     DI,BX
  3508.         DEC     DI
  3509.         REPNE   SCASB
  3510.         JE      @@2
  3511.         SUB     BX,DS:[SI].TEditor.GapLen
  3512.         MOV     DI,DS:[SI].TEditor.CurPtr
  3513. @@1:    MOV     CX,DI
  3514.         JCXZ    @@4
  3515.         ADD     DI,BX
  3516.         DEC     DI
  3517.         REPNE   SCASB
  3518.         JNE     @@3
  3519. @@2:    INC     DI
  3520.         INC     DI
  3521.         SUB     DI,BX
  3522.         CMP     DI,DS:[SI].TEditor.CurPtr
  3523.         JE      @@4
  3524.         CMP     DI,DS:[SI].TEditor.BufLen
  3525.         JE      @@4
  3526.         CMP     ES:[BX+DI].Byte,0AH
  3527.         JNE     @@4
  3528.         INC     DI
  3529.         JMP     @@4
  3530. @@3:    XOR     DI,DI
  3531. @@4:    MOV     AX,DI
  3532.         POP     DS
  3533.  
  3534.  
  3535. end; { TEditor.LineStart }
  3536.  
  3537.  
  3538.  
  3539. { -------------------------------------------------------------------------- }
  3540.  
  3541.  
  3542.  
  3543. procedure TEditor.Lock;
  3544.  
  3545. begin
  3546.  
  3547.   Inc (LockCount);
  3548.  
  3549.  
  3550. end; { TEditor.Lock }
  3551.  
  3552.  
  3553.  
  3554. { -------------------------------------------------------------------------- }
  3555.  
  3556.  
  3557.  
  3558. { WRAP - Start. }
  3559.  
  3560. procedure TEditor.NewLine (Select_Mode : Byte);
  3561.  
  3562.  
  3563.  
  3564. CONST
  3565.  
  3566.   CrLf : array[1..2] of Char = #13#10;
  3567.  
  3568. VAR
  3569.  
  3570.   I : Word;          { Used to track spaces for AutoIndent.                 }
  3571.   P : Word;          { Position of Cursor when we arrive and after Newline. }
  3572.  
  3573. begin
  3574.  
  3575.   P := LineStart (CurPtr);
  3576.   I := P;
  3577.  
  3578.  
  3579.  
  3580.   { -------------------------------------------------------- }
  3581.   {                                                          }
  3582.   { The first thing we do is remove any End Of Line spaces.  }
  3583.   { Then we check to see how many spaces are on beginning    }
  3584.   { of a line.   We need this check to add them after CR/LF  }
  3585.   { if AutoIndenting.  Last of all we insert spaces required }
  3586.   { for the AutoIndenting, if it was on.                     }
  3587.   {                                                          }
  3588.   { -------------------------------------------------------- }
  3589.  
  3590.  
  3591.   Remove_EOL_Spaces (Select_Mode);
  3592.  
  3593.   while (I < CurPtr) and ((Buffer^[I] = ' ') or (Buffer^[I] = #9)) do
  3594.      Inc (I);
  3595.  
  3596.   InsertText (@CrLf, 2, False);
  3597.  
  3598.   if AutoIndent then
  3599.     InsertText (@Buffer^[P], I - P, False);
  3600.  
  3601.  
  3602.  
  3603.   { ------------------------------------------------ }
  3604.   {                                                  }
  3605.   { Remember where the CurPtr is at this moment.     }
  3606.   { Remember the length of the buffer at the moment. }
  3607.   { Go to the previous line and remove EOL spaces.   }
  3608.   { Once removed, re-set the cursor to where we were }
  3609.   { minus any spaces that might have been removed.   }
  3610.   {                                                  }
  3611.   { ------------------------------------------------ }
  3612.  
  3613.  
  3614.   I := BufLen;
  3615.   P := CurPtr;
  3616.  
  3617.   SetCurPtr (LineMove (CurPtr, - 1), Select_Mode);
  3618.   Remove_EOL_Spaces (Select_Mode);
  3619.  
  3620.   if I - BufLen <> 0 then
  3621.     SetCurPtr (P - (I - BufLen), Select_Mode)
  3622.   else
  3623.     SetCurPtr (P, Select_Mode);
  3624.  
  3625.  
  3626. end; { TEditor.NewLine }
  3627.  
  3628. { WRAP - Stop. } { Added new parameter and new code to support wordwrap. }
  3629.  
  3630.  
  3631.  
  3632. { -------------------------------------------------------------------------- }
  3633.  
  3634.  
  3635.  
  3636. function TEditor.NextChar (P : Word) : Word; assembler;
  3637.  
  3638. asm
  3639.         PUSH    DS
  3640.         LDS     SI,Self
  3641.         MOV     DI,P
  3642.         CMP     DI,DS:[SI].TEditor.BufLen
  3643.         JE      @@2
  3644.         INC     DI
  3645.         CMP     DI,DS:[SI].TEditor.BufLen
  3646.         JE      @@2
  3647.         LES     BX,DS:[SI].TEditor.Buffer
  3648.         CMP     DI,DS:[SI].TEditor.CurPtr
  3649.         JB      @@1
  3650.         ADD     BX,DS:[SI].TEditor.GapLen
  3651. @@1:    CMP     ES:[BX+DI-1].Word,0A0DH
  3652.         JNE     @@2
  3653.         INC     DI
  3654. @@2:    MOV     AX,DI
  3655.         POP     DS
  3656.  
  3657.  
  3658. end; { TEditor.NextChar }
  3659.  
  3660.  
  3661.  
  3662. { -------------------------------------------------------------------------- }
  3663.  
  3664.  
  3665.  
  3666. function TEditor.NextLine (P : Word) : Word;
  3667.  
  3668. begin
  3669.  
  3670.   NextLine := NextChar (LineEnd (P));
  3671.  
  3672.  
  3673. end; { TEditor.NextLine }
  3674.  
  3675.  
  3676.  
  3677. { -------------------------------------------------------------------------- }
  3678.  
  3679.  
  3680.  
  3681. function TEditor.NextWord (P : Word) : Word;
  3682.  
  3683.  
  3684. begin
  3685.  
  3686.   while (P < BufLen) and (BufChar (P) in WordChars) do
  3687.     P := NextChar (P);
  3688.  
  3689.   while (P < BufLen) and not (BufChar (P) in WordChars) do
  3690.     P := NextChar (P);
  3691.  
  3692.   NextWord := P;
  3693.  
  3694.  
  3695. end; { TEditor.NextWord }
  3696.  
  3697.  
  3698.  
  3699. { -------------------------------------------------------------------------- }
  3700.  
  3701.  
  3702.  
  3703. function TEditor.PrevChar (P : Word) : Word; assembler;
  3704.  
  3705. asm
  3706.         PUSH    DS
  3707.         LDS     SI,Self
  3708.         MOV     DI,P
  3709.         OR      DI,DI
  3710.         JE      @@2
  3711.         DEC     DI
  3712.         JE      @@2
  3713.         LES     BX,DS:[SI].TEditor.Buffer
  3714.         CMP     DI,DS:[SI].TEditor.CurPtr
  3715.         JB      @@1
  3716.         ADD     BX,DS:[SI].TEditor.GapLen
  3717. @@1:    CMP     ES:[BX+DI-1].Word,0A0DH
  3718.         JNE     @@2
  3719.         DEC     DI
  3720. @@2:    MOV     AX,DI
  3721.         POP     DS
  3722.  
  3723.  
  3724. end; { TEditor.PrevChar }
  3725.  
  3726.  
  3727.  
  3728. { -------------------------------------------------------------------------- }
  3729.  
  3730.  
  3731.  
  3732. function TEditor.PrevLine (P : Word) : Word;
  3733.  
  3734. begin
  3735.  
  3736.   PrevLine := LineStart (PrevChar (P));
  3737.  
  3738.  
  3739. end; { TEditor.PrevLine }
  3740.  
  3741.  
  3742.  
  3743. { -------------------------------------------------------------------------- }
  3744.  
  3745.  
  3746.  
  3747. function TEditor.PrevWord (P : Word) : Word;
  3748.  
  3749. begin
  3750.  
  3751.   while (P > 0) and not (BufChar (PrevChar (P)) in WordChars) do
  3752.     P := PrevChar (P);
  3753.  
  3754.   while (P > 0) and (BufChar (PrevChar (P)) in WordChars) do
  3755.     P := PrevChar (P);
  3756.  
  3757.   PrevWord := P;
  3758.  
  3759.  
  3760. end; { TEditor.PrevWord }
  3761.  
  3762.  
  3763.  
  3764. { -------------------------------------------------------------------------- }
  3765.  
  3766.  
  3767.  
  3768. { REFDOC - Start. }
  3769.  
  3770. procedure TEditor.Reformat_Document (Select_Mode : Byte; Center_Cursor : Boolean);
  3771.  
  3772.  
  3773.   { -------------------------------------------------------------------- }
  3774.   {                                                                      }
  3775.   { This procedure will do a reformat of the entire document, or just    }
  3776.   { from the current line to the end of the document, if ^QU is pressed. }
  3777.   { It simply brings up the correct dialog box, and then calls the       }
  3778.   { TEditor.Reformat_Paragraph procedure to do the actual reformatting.  }
  3779.   {                                                                      }
  3780.   { -------------------------------------------------------------------- }
  3781.  
  3782.  
  3783. CONST
  3784.  
  3785.   efCurrentLine   = $0000;  { Radio button #1 selection for dialog box.  }
  3786.   efWholeDocument = $0001;  { Radio button #2 selection for dialog box.  }
  3787.  
  3788. VAR
  3789.  
  3790.   Reformat_Options : Word;  { Holds the dialog options for reformatting. }
  3791.  
  3792.  
  3793. begin
  3794.  
  3795.  
  3796.  
  3797.   { ----------------------------------------------------------------- }
  3798.   {                                                                   }
  3799.   { Check if Word_Wrap is toggled on.  If NOT on, check if programmer }
  3800.   { allows reformatting of document and if not show user dialog that  }
  3801.   { says reformatting is not permissable.                             }
  3802.   {                                                                   }
  3803.   { ----------------------------------------------------------------- }
  3804.  
  3805.  
  3806.   if not Word_Wrap then
  3807.     begin
  3808.       if not Allow_Reformat then
  3809.         begin
  3810.           EditorDialog (edReformatNotAllowed, nil);
  3811.           Exit;
  3812.         end;
  3813.       Word_Wrap := True;
  3814.       Update (ufStats);
  3815.     end;
  3816.  
  3817.  
  3818.  
  3819.   { ------------------------------------------------------------- }
  3820.   {                                                               }
  3821.   { Default radio button option to 1st one.  Bring up dialog box. }
  3822.   {                                                               }
  3823.   { ------------------------------------------------------------- }
  3824.  
  3825.  
  3826.   Reformat_Options := efCurrentLine;
  3827.  
  3828.   if EditorDialog (edReformatDocument, @Reformat_Options) <> Views.cmCancel then
  3829.     begin
  3830.  
  3831.  
  3832.  
  3833.       { ----------------------------------------------------------- }
  3834.       {                                                             }
  3835.       { If the option to reformat the whole document was selected   }
  3836.       { we need to go back to start of document.  Otherwise we stay }
  3837.       { on the current line.  Call Reformat_Paragraph until we get  }
  3838.       { to the end of the document to do the reformatting.          }
  3839.       {                                                             }
  3840.       { ----------------------------------------------------------- }
  3841.  
  3842.  
  3843.       if Reformat_Options and efWholeDocument <> 0 then
  3844.         SetCurPtr (0, Select_Mode);
  3845.  
  3846.       Unlock;
  3847.  
  3848.       repeat
  3849.         Lock;
  3850.  
  3851.         if NOT Reformat_Paragraph (Select_Mode, Center_Cursor) then
  3852.           Exit;
  3853.  
  3854.         TrackCursor (False);
  3855.         Unlock;
  3856.       until CurPtr = BufLen;
  3857.  
  3858.     end;
  3859.  
  3860.  
  3861. end; { TEditor.Reformat_Document }
  3862.  
  3863. { REFDOC - Stop. }
  3864.  
  3865.  
  3866.  
  3867. { -------------------------------------------------------------------------- }
  3868.  
  3869.  
  3870.  
  3871. { REFORM - Start. }
  3872.  
  3873. function TEditor.Reformat_Paragraph (Select_Mode   : Byte;
  3874.                                      Center_Cursor : Boolean) : Boolean;
  3875.  
  3876.  
  3877.   { ------------------------------------------------------------------------- }
  3878.   {                                                                           }
  3879.   { This procedure will do a reformat of the current paragraph if ^B pressed. }
  3880.   { The feature works regardless if wordrap is on or off.  It also supports   }
  3881.   { the AutoIndent feature.  Reformat is not possible if the CurPos exceeds   }
  3882.   { the Right_Margin.  Right_Margin is where the EOL is considered to be.     }
  3883.   {                                                                           }
  3884.   { ------------------------------------------------------------------------- }
  3885.  
  3886.  
  3887. CONST
  3888.  
  3889.   Space : array [1..2] of Char = #32#32;
  3890.  
  3891. VAR
  3892.  
  3893.   C : Word;  { Position of CurPtr when we come into procedure. }
  3894.   E : Word;  { End of a line.                                  }
  3895.   S : Word;  { Start of a line.                                }
  3896.  
  3897. begin
  3898.  
  3899.   Reformat_Paragraph := False;
  3900.  
  3901.  
  3902.  
  3903.   { ----------------------------------------------------------------- }
  3904.   {                                                                   }
  3905.   { Check if Word_Wrap is toggled on.  If NOT on, check if programmer }
  3906.   { allows reformatting of paragraph and if not show user dialog that }
  3907.   { says reformatting is not permissable.                             }
  3908.   {                                                                   }
  3909.   { ----------------------------------------------------------------- }
  3910.  
  3911.  
  3912.   if not Word_Wrap then
  3913.     begin
  3914.       if not Allow_Reformat then
  3915.         begin
  3916.           EditorDialog (edReformatNotAllowed, nil);
  3917.           Exit;
  3918.         end;
  3919.       Word_Wrap := True;
  3920.       Update (ufStats);
  3921.     end;
  3922.  
  3923.  
  3924.  
  3925.   C := CurPtr;
  3926.   E := LineEnd (CurPtr);
  3927.   S := LineStart (CurPtr);
  3928.  
  3929.  
  3930.  
  3931.   { ---------------------------------------------------- }
  3932.   {                                                      }
  3933.   { Reformat possible only if current line is NOT blank! }
  3934.   {                                                      }
  3935.   { ---------------------------------------------------- }
  3936.  
  3937.  
  3938.   if E <> S then
  3939.     begin
  3940.  
  3941.  
  3942.  
  3943.       { ------------------------------------------ }
  3944.       {                                            }
  3945.       { Reformat is NOT possible if the first word }
  3946.       { on the line is beyond the Right_Margin.    }
  3947.       {                                            }
  3948.       { ------------------------------------------ }
  3949.  
  3950.  
  3951.       S := LineStart (CurPtr);
  3952.  
  3953.       if NextWord (S) - S >= Right_Margin - 1 then
  3954.         begin
  3955.           EditorDialog (edReformNotPossible, nil);
  3956.           Exit;
  3957.         end;
  3958.  
  3959.  
  3960.  
  3961.       { ----------------------------------------------- }
  3962.       {                                                 }
  3963.       { First objective is to find the first blank line }
  3964.       { after this paragraph so we know when to stop.   }
  3965.       { That could be the end of the document.          }
  3966.       {                                                 }
  3967.       { ----------------------------------------------- }
  3968.  
  3969.  
  3970.       Repeat
  3971.         SetCurPtr (LineMove (CurPtr, 1), Select_Mode);
  3972.         E := LineEnd (CurPtr);
  3973.         S := LineStart (CurPtr);
  3974.         BlankLine := E;
  3975.       until ((CurPtr = BufLen) or (E = S));
  3976.  
  3977.       SetCurPtr (C, Select_Mode);
  3978.  
  3979.       repeat
  3980.  
  3981.  
  3982.  
  3983.         { ------------------------------------------------ }
  3984.         {                                                  }
  3985.         { Set CurPtr to LineEnd and remove the EOL spaces. }
  3986.         { Pull up the next line and remove its EOL space.  }
  3987.         { First make sure the next line is not BlankLine!  }
  3988.         { Insert spaces as required between the two lines. }
  3989.         {                                                  }
  3990.         { ------------------------------------------------ }
  3991.  
  3992.  
  3993.         SetCurPtr (LineEnd (CurPtr), Select_Mode);
  3994.         Remove_EOL_Spaces (Select_Mode);
  3995.         if CurPtr <> Blankline - 2 then
  3996.           DeleteRange (CurPtr, Nextword (CurPtr), True);
  3997.         Remove_EOL_Spaces (Select_Mode);
  3998.  
  3999.         case Buffer^[CurPtr-1] of
  4000.           '!' : InsertText (@Space, 2, False);
  4001.           '.' : InsertText (@Space, 2, False);
  4002.           ':' : InsertText (@Space, 2, False);
  4003.           '?' : InsertText (@Space, 2, False);
  4004.         else
  4005.           InsertText (@Space, 1, False);
  4006.         end;
  4007.  
  4008.  
  4009.  
  4010.         { --------------------------------------------------------- }
  4011.         {                                                           }
  4012.         { Reset CurPtr to EOL.  While line length is > Right_Margin }
  4013.         { go Do_Word_Wrap.  If wordrap failed, exit routine.        }
  4014.         {                                                           }
  4015.         { --------------------------------------------------------- }
  4016.  
  4017.  
  4018.         SetCurPtr (LineEnd (CurPtr), Select_Mode);
  4019.  
  4020.         while LineEnd (CurPtr) - LineStart (CurPtr) > Right_Margin do
  4021.           begin
  4022.             if not Do_Word_Wrap (Select_Mode, Center_Cursor) then
  4023.               Exit;
  4024.           end;
  4025.  
  4026.  
  4027.  
  4028.         { -------------------------------------------------------- }
  4029.         {                                                          }
  4030.         { If LineEnd - LineStart > Right_Margin then set CurPtr    }
  4031.         { to Right_Margin on current line.  Otherwise we set the   }
  4032.         { CurPtr to LineEnd.  This gyration sets up the conditions }
  4033.         { to test for time of loop exit.                           }
  4034.         {                                                          }
  4035.         { -------------------------------------------------------- }
  4036.  
  4037.  
  4038.         if LineEnd (CurPtr) - LineStart (CurPtr) > Right_Margin then
  4039.           SetCurPtr (LineStart (CurPtr) + Right_Margin, Select_Mode)
  4040.         else
  4041.           SetCurPtr (LineEnd (CurPtr), Select_Mode);
  4042.  
  4043.       until ((CurPtr >= BufLen) or (CurPtr >= BlankLine - 2));
  4044.  
  4045.     end;
  4046.  
  4047.  
  4048.  
  4049.   { --------------------------------------------------------------------- }
  4050.   {                                                                       }
  4051.   { If not at the end of the document reset CurPtr to start of next line. }
  4052.   { This should be a blank line between paragraphs.                       }
  4053.   {                                                                       }
  4054.   { --------------------------------------------------------------------- }
  4055.  
  4056.  
  4057.   if CurPtr < BufLen then
  4058.     SetCurPtr (LineMove (CurPtr, 1), Select_Mode);
  4059.  
  4060.  
  4061.   Reformat_Paragraph := True;
  4062.  
  4063.  
  4064. end; { TEditor.Reformat_Paragraph }
  4065.  
  4066. { REFORM - Stop. }
  4067.  
  4068.  
  4069.  
  4070. { -------------------------------------------------------------------------- }
  4071.  
  4072.  
  4073.  
  4074. { WRAP - Start. }
  4075.  
  4076. procedure TEditor.Remove_EOL_Spaces (Select_Mode : Byte);
  4077.  
  4078.  
  4079.   { ----------------------------------------------------------- }
  4080.   {                                                             }
  4081.   { This procedure tests to see if there are consecutive spaces }
  4082.   { at the end of a line (EOL).  If so, we delete all spaces    }
  4083.   { after the last non-space character to the end of line.      }
  4084.   { We then reset the CurPtr to where we ended up at.           }
  4085.   {                                                             }
  4086.   { ----------------------------------------------------------- }
  4087.  
  4088.  
  4089. VAR
  4090.  
  4091.   C : Word;           { Current pointer when we come into procedure. }
  4092.   E : Word;           { End of line.                                 }
  4093.   P : Word;           { Position of pointer at any given moment.     }
  4094.   S : Word;           { Start of a line.                             }
  4095.  
  4096. begin
  4097.  
  4098.   C := CurPtr;
  4099.   E := LineEnd (CurPtr);
  4100.   P := E;
  4101.   S := LineStart (CurPtr);
  4102.  
  4103.  
  4104.  
  4105.   { ------------------------------------------------------ }
  4106.   {                                                        }
  4107.   { Start at the end of a line and move towards the start. }
  4108.   { Find first non-space character in that direction.      }
  4109.   {                                                        }
  4110.   { ------------------------------------------------------ }
  4111.  
  4112.  
  4113.   while (P > S) and (BufChar (PrevChar (P)) = #32) do
  4114.     P := PrevChar (P);
  4115.  
  4116.  
  4117.  
  4118.   { ---------------------------------------- }
  4119.   {                                          }
  4120.   { If we found any spaces then delete them. }
  4121.   {                                          }
  4122.   { ---------------------------------------- }
  4123.  
  4124.  
  4125.   if P < E then
  4126.     begin
  4127.  
  4128.       SetSelect (P, E, True);
  4129.       DeleteSelect;
  4130.  
  4131.       { MARK - Start. }
  4132.  
  4133.       Update_Place_Markers (0, E - P, P, E);
  4134.  
  4135.       { MARK - Stop. } { This will update Place_Marker for EOL deletions. }
  4136.                        { All other deletions are handled by DeleteRange.  }
  4137.  
  4138.     end;
  4139.  
  4140.  
  4141.  
  4142.   { --------------------------------------------------- }
  4143.   {                                                     }
  4144.   { If C, our pointer when we came into this procedure, }
  4145.   { is less than the CurPtr then reset CurPtr to C so   }
  4146.   { cursor is where we started.  Otherwise, set it to   }
  4147.   { the new CurPtr, for we have deleted characters.     }
  4148.   {                                                     }
  4149.   { --------------------------------------------------- }
  4150.  
  4151.  
  4152.   if C < CurPtr then
  4153.     SetCurPtr (C, Select_Mode)
  4154.   else
  4155.     SetCurPtr (CurPtr, Select_Mode);
  4156.  
  4157.  
  4158. end; { TEditor.Remove_EOL_Spaces }
  4159.  
  4160. { WRAP - Stop. }
  4161.  
  4162.  
  4163.  
  4164. { -------------------------------------------------------------------------- }
  4165.  
  4166.  
  4167.  
  4168. procedure TEditor.Replace;
  4169.  
  4170. VAR
  4171.  
  4172.   ReplaceRec : TReplaceDialogRec;
  4173.  
  4174. begin
  4175.  
  4176.   with ReplaceRec do
  4177.   begin
  4178.  
  4179.     Find := FindStr;
  4180.     Replace := ReplaceStr;
  4181.     Options := EditorFlags;
  4182.  
  4183.     if EditorDialog (edReplace, @ReplaceRec) <> Views.cmCancel then
  4184.     begin
  4185.       FindStr := Find;
  4186.       ReplaceStr := Replace;
  4187.       EditorFlags := Options or efDoReplace;
  4188.       DoSearchReplace;
  4189.     end;
  4190.   end;
  4191.  
  4192.  
  4193. end; { TEditor.Replace }
  4194.  
  4195.  
  4196.  
  4197. { -------------------------------------------------------------------------- }
  4198.  
  4199.  
  4200.  
  4201. { SCRLDN - Start. }
  4202.  
  4203. procedure TEditor.Scroll_Down;
  4204.  
  4205.  
  4206.   { -------------------------------------------------------------- }
  4207.   {                                                                }
  4208.   { This procedure will scroll the screen up, and always keep      }
  4209.   { the cursor on the CurPos.Y position, but not necessarily on    }
  4210.   { the CurPos.X.  If CurPos.Y scrolls off the screen, the cursor  }
  4211.   { will stay in the upper left corner of the screen.  This will   }
  4212.   { simulate the same process in the IDE.  The CurPos.X coordinate }
  4213.   { only messes up if we are on long lines and we then encounter   }
  4214.   { a shorter or blank line beneath the current one as we scroll.  }
  4215.   { In that case, it goes to the end of the new line.              }
  4216.   {                                                                }
  4217.   { -------------------------------------------------------------- }
  4218.  
  4219.  
  4220. VAR
  4221.  
  4222.   C : Word;           { Position of CurPtr when we enter procedure. }
  4223.   P : Word;           { Position of CurPtr at any given time.       }
  4224.   W : Objects.TPoint; { CurPos.Y of CurPtr and P ('.X and '.Y).     }
  4225.  
  4226. begin
  4227.  
  4228.  
  4229.  
  4230.   { ---------------------------------------------------------------------- }
  4231.   {                                                                        }
  4232.   { Remember current cursor position.  Remember current CurPos.Y position. }
  4233.   { Now issue the equivalent of a [Ctrl]-[End] command so the cursor will  }
  4234.   { go to the bottom of the current screen.  Reset the cursor to this new  }
  4235.   { position and then send FALSE to TrackCursor so we fool it into         }
  4236.   { incrementing Delta.Y by only +1.  If we didn't do this it would try    }
  4237.   { to center the cursor on the screen by fiddling with Delta.Y.           }
  4238.   {                                                                        }
  4239.   { ---------------------------------------------------------------------- }
  4240.  
  4241.  
  4242.   C := CurPtr;
  4243.   W.X := CurPos.Y;
  4244.  
  4245.   P := LineMove (CurPtr, Delta.Y - CurPos.Y + Size.Y);
  4246.  
  4247.   SetCurPtr (P, 0);
  4248.  
  4249.   TrackCursor (False);
  4250.  
  4251.  
  4252.  
  4253.   { -------------------------------------------------------------------- }
  4254.   {                                                                      }
  4255.   { Now remember where the new CurPos.Y is.  See if distance between new }
  4256.   { CurPos.Y and old CurPos.Y are greater than the current screen size.  }
  4257.   { If they are, we need to move cursor position itself down by one.     }
  4258.   { Otherwise, send the cursor back to our original CurPtr.              }
  4259.   {                                                                      }
  4260.   { -------------------------------------------------------------------- }
  4261.  
  4262.  
  4263.   W.Y := CurPos.Y;
  4264.  
  4265.   if W.Y - W.X > Size.Y - 1 then
  4266.     SetCurPtr (LineMove (C, 1), 0)
  4267.   else
  4268.     SetCurPtr (C, 0);
  4269.  
  4270.  
  4271. end; { TEditor.Scroll_Down }
  4272.  
  4273. { SCRLDN - Stop. } { Added this complete procedure to simulate IDE function. }
  4274.  
  4275.  
  4276.  
  4277. { -------------------------------------------------------------------------- }
  4278.  
  4279.  
  4280.  
  4281. { SCRLUP - Start. }
  4282.  
  4283. procedure TEditor.Scroll_Up;
  4284.  
  4285.  
  4286.   { -------------------------------------------------------------- }
  4287.   {                                                                }
  4288.   { This procedure will scroll the screen down, and always keep    }
  4289.   { the cursor on the CurPos.Y position, but not necessarily on    }
  4290.   { the CurPos.X.  If CurPos.Y scrolls off the screen, the cursor  }
  4291.   { will stay in the bottom left corner of the screen.  This will  }
  4292.   { simulate the same process in the IDE.  The CurPos.X coordinate }
  4293.   { only messes up if we are on long lines and we then encounter   }
  4294.   { a shorter or blank line beneath the current one as we scroll.  }
  4295.   { In that case, it goes to the end of the new line.              }
  4296.   {                                                                }
  4297.   { -------------------------------------------------------------- }
  4298.  
  4299.  
  4300. VAR
  4301.  
  4302.   C : Word;           { Position of CurPtr when we enter procedure. }
  4303.   P : Word;           { Position of CurPtr at any given time.       }
  4304.   W : Objects.TPoint; { CurPos.Y of CurPtr and P ('.X and '.Y).     }
  4305.  
  4306. begin
  4307.  
  4308.  
  4309.  
  4310.   { ---------------------------------------------------------------------- }
  4311.   {                                                                        }
  4312.   { Remember current cursor position.  Remember current CurPos.Y position. }
  4313.   { Now issue the equivalent of a [Ctrl]-[Home] command so the cursor will }
  4314.   { go to the top of the current screen.  Reset the cursor to this new     }
  4315.   { position and then send FALSE to TrackCursor so we fool it into         }
  4316.   { decrementing Delta.Y by only -1.  If we didn't do this it would try    }
  4317.   { to center the cursor on the screen by fiddling with Delta.Y.           }
  4318.   {                                                                        }
  4319.   { ---------------------------------------------------------------------- }
  4320.  
  4321.  
  4322.   C := CurPtr;
  4323.   W.Y := CurPos.Y;
  4324.  
  4325.   P := LineMove (CurPtr, -(CurPos.Y - Delta.Y + 1));
  4326.  
  4327.   SetCurPtr (P, 0);
  4328.  
  4329.   TrackCursor (False);
  4330.  
  4331.  
  4332.  
  4333.   { -------------------------------------------------------------------- }
  4334.   {                                                                      }
  4335.   { Now remember where the new CurPos.Y is.  See if distance between new }
  4336.   { CurPos.Y and old CurPos.Y are greater than the current screen size.  }
  4337.   { If they are, we need to move the cursor position itself up by one.   }
  4338.   { Otherwise, send the cursor back to our original CurPtr.              }
  4339.   {                                                                      }
  4340.   { -------------------------------------------------------------------- }
  4341.  
  4342.  
  4343.   W.X := CurPos.Y;
  4344.  
  4345.   if W.Y - W.X > Size.Y - 1 then
  4346.     SetCurPtr (LineMove (C, -1), 0)
  4347.   else
  4348.     SetCurPtr (C, 0);
  4349.  
  4350.  
  4351. end; { TEditor.Scroll_Up }
  4352.  
  4353. { SCRLDN - Stop. } { Added this complete procedure to simulate IDE function. }
  4354.  
  4355.  
  4356.  
  4357. { -------------------------------------------------------------------------- }
  4358.  
  4359.  
  4360.  
  4361. procedure TEditor.ScrollTo (X, Y : Integer);
  4362.  
  4363. begin
  4364.  
  4365.   X := Max (0, Min (X, Limit.X - Size.X));
  4366.   Y := Max (0, Min (Y, Limit.Y - Size.Y));
  4367.  
  4368.   if (X <> Delta.X) or (Y <> Delta.Y) then
  4369.   begin
  4370.     Delta.X := X;
  4371.     Delta.Y := Y;
  4372.     Update (ufView);
  4373.   end;
  4374.  
  4375.  
  4376. end; { TEditor.ScrollTo }
  4377.  
  4378.  
  4379.  
  4380. { -------------------------------------------------------------------------- }
  4381.  
  4382.  
  4383.  
  4384. function TEditor.Search (FindStr : String; Opts : Word) : Boolean;
  4385.  
  4386. VAR
  4387.  
  4388.   I   : Word;
  4389.   Pos : Word;
  4390.  
  4391. begin
  4392.  
  4393.   Search := False;
  4394.   Pos := CurPtr;
  4395.  
  4396.   repeat
  4397.  
  4398.     if Opts and efCaseSensitive <> 0 then
  4399.       I := Scan (Buffer^[BufPtr (Pos)], BufLen - Pos, FindStr)
  4400.     else
  4401.       I := IScan (Buffer^[BufPtr (Pos)], BufLen - Pos, FindStr);
  4402.  
  4403.     if (I <> sfSearchFailed) then
  4404.     begin
  4405.  
  4406.       Inc (I, Pos);
  4407.  
  4408.       if (Opts and efWholeWordsOnly = 0) or
  4409.          not (((I <> 0) and (BufChar (I - 1) in WordChars)) or
  4410.               ((I + Length (FindStr) <> BufLen) and
  4411.                (BufChar (I + Length (FindStr)) in WordChars))) then
  4412.         begin
  4413.           Lock;
  4414.           SetSelect (I, I + Length (FindStr), False);
  4415.           TrackCursor (not CursorVisible);
  4416.           Unlock;
  4417.           Search := True;
  4418.           Exit;
  4419.         end
  4420.       else
  4421.         Pos := I + 1;
  4422.  
  4423.     end;
  4424.  
  4425.   until I = sfSearchFailed;
  4426.  
  4427.  
  4428. end; { TEditor.Search }
  4429.  
  4430.  
  4431.  
  4432. { -------------------------------------------------------------------------- }
  4433.  
  4434.  
  4435.  
  4436. { SELWRD - Start. }
  4437.  
  4438. procedure TEditor.Select_Word;
  4439.  
  4440.  
  4441.   { ------------------------------------------------------------------ }
  4442.   {                                                                    }
  4443.   { This procedure will select the a word to put into the clipboard.   }
  4444.   { I've added it just to maintain compatibility with the IDE editor.  }
  4445.   { Note that selection starts at the current cursor position and ends }
  4446.   { when a space or the end of line is encountered.                    }
  4447.   {                                                                    }
  4448.   { ------------------------------------------------------------------ }
  4449.  
  4450.  
  4451. VAR
  4452.  
  4453.   E : Word;           { End of the current line.                           }
  4454.   Select_Mode : Byte; { Allows us to turn select mode on inside procedure. }
  4455.  
  4456. begin
  4457.  
  4458.   E := LineEnd (CurPtr);
  4459.  
  4460.  
  4461.  
  4462.   { ----------------------------------------------------------- }
  4463.   {                                                             }
  4464.   { If the cursor is on a space or at the end of a line, abort. }
  4465.   { Stupid action on users part for you can't select blanks!    }
  4466.   {                                                             }
  4467.   { ----------------------------------------------------------- }
  4468.  
  4469.  
  4470.   if (BufChar (CurPtr) = #32) or (CurPtr = E) then
  4471.     Exit;
  4472.  
  4473.  
  4474.  
  4475.   { ------------------------------------------------------------ }
  4476.   {                                                              }
  4477.   { Turn on select mode and tell editor to start selecting text. }
  4478.   { As long as we have a character > a space (this is done to    }
  4479.   { exclude CR/LF pairs at end of a line) and we are NOT at the  }
  4480.   { end of a line, set the CurPtr to the next character.         }
  4481.   { Once we find a space or CR/LF, selection is done and we      }
  4482.   { automatically put the selected word into the Clipboard.      }
  4483.   {                                                              }
  4484.   { ------------------------------------------------------------ }
  4485.  
  4486.  
  4487.   Select_Mode := smExtend;
  4488.   StartSelect;
  4489.  
  4490.   while (BufChar (NextChar (CurPtr)) > #32) and (CurPtr < E) do
  4491.     SetCurPtr (NextChar (CurPtr), Select_Mode);
  4492.  
  4493.   SetCurPtr (NextChar (CurPtr), Select_Mode);
  4494.   ClipCopy;
  4495.  
  4496.  
  4497. end; {TEditor.Select_Word }
  4498.  
  4499. {SELWRD - Stop. }
  4500.  
  4501.  
  4502.  
  4503. { -------------------------------------------------------------------------- }
  4504.  
  4505.  
  4506.  
  4507. procedure TEditor.SetBufLen (Length : Word);
  4508.  
  4509.  
  4510. begin
  4511.  
  4512.   BufLen := Length;
  4513.   GapLen := BufSize - Length;
  4514.  
  4515.   SelStart := 0;
  4516.   SelEnd := 0;
  4517.  
  4518.   CurPtr := 0;
  4519.  
  4520.   Longint (CurPos) := 0;
  4521.   Longint (Delta) := 0;
  4522.  
  4523.   Limit.X := MaxLineLength;
  4524.   Limit.Y := CountLines (Buffer^[GapLen], BufLen) + 1;
  4525.  
  4526.   DrawLine := 0;
  4527.   DrawPtr := 0;
  4528.  
  4529.   DelCount := 0;
  4530.   InsCount := 0;
  4531.  
  4532.   Modified := False;
  4533.   Update (ufView);
  4534.  
  4535.  
  4536. end; { TEditor.SetBufLen }
  4537.  
  4538.  
  4539.  
  4540. { -------------------------------------------------------------------------- }
  4541.  
  4542.  
  4543.  
  4544. function TEditor.SetBufSize (NewSize : Word) : Boolean;
  4545.  
  4546. begin
  4547.  
  4548.   SetBufSize := NewSize <= BufSize;
  4549.  
  4550.  
  4551. end; { TEditor.SetBufSize }
  4552.  
  4553.  
  4554.  
  4555. { -------------------------------------------------------------------------- }
  4556.  
  4557.  
  4558.  
  4559. procedure TEditor.SetCmdState (Command : Word; Enable : Boolean);
  4560.  
  4561. VAR
  4562.  
  4563.   S : Views.TCommandSet;
  4564.  
  4565. begin
  4566.  
  4567.   S := [Command];
  4568.  
  4569.   if Enable and (State and sfActive <> 0) then
  4570.     EnableCommands (S)
  4571.   else
  4572.     DisableCommands (S);
  4573.  
  4574.  
  4575. end; { TEditor.SetCmdState }
  4576.  
  4577.  
  4578.  
  4579. { -------------------------------------------------------------------------- }
  4580.  
  4581.  
  4582.  
  4583. procedure TEditor.SetCurPtr (P : Word; SelectMode : Byte);
  4584.  
  4585. VAR
  4586.  
  4587.   Anchor : Word;
  4588.  
  4589. begin
  4590.  
  4591.   if SelectMode and smExtend = 0 then
  4592.     Anchor := P
  4593.   else
  4594.     if CurPtr = SelStart then
  4595.       Anchor := SelEnd
  4596.     else
  4597.       Anchor := SelStart;
  4598.  
  4599.   if P < Anchor then
  4600.     begin
  4601.  
  4602.       if SelectMode and smDouble <> 0 then
  4603.       begin
  4604.         P := PrevLine (NextLine (P));
  4605.         Anchor := NextLine (PrevLine (Anchor));
  4606.       end;
  4607.  
  4608.       SetSelect (P, Anchor, True);
  4609.  
  4610.     end
  4611.   else
  4612.     begin
  4613.  
  4614.       if SelectMode and smDouble <> 0 then
  4615.       begin
  4616.         P := NextLine (P);
  4617.         Anchor := PrevLine (NextLine (Anchor));
  4618.       end;
  4619.  
  4620.       SetSelect (Anchor, P, False);
  4621.  
  4622.     end;
  4623.  
  4624.  
  4625. end; { TEditor.SetCurPtr }
  4626.  
  4627.  
  4628.  
  4629. { -------------------------------------------------------------------------- }
  4630.  
  4631.  
  4632.  
  4633. { MARK - Start. }
  4634.  
  4635. procedure TEditor.Set_Place_Marker (Element : Byte);
  4636.  
  4637.  
  4638.   { -------------------------------------------------------------------- }
  4639.   {                                                                      }
  4640.   { This procedure sets a place marker for the CurPtr if ^K# is pressed. }
  4641.   {                                                                      }
  4642.   { -------------------------------------------------------------------- }
  4643.  
  4644.  
  4645. begin
  4646.  
  4647.   if not IsClipboard then
  4648.     Place_Marker[Element] := CurPtr;
  4649.  
  4650.  
  4651. end; { TEditor.Set_Place_Marker }
  4652.  
  4653. { MARK - Stop. }
  4654.  
  4655.  
  4656.  
  4657. { -------------------------------------------------------------------------- }
  4658.  
  4659.  
  4660.  
  4661. { RMSET - Start. }
  4662.  
  4663. procedure TEditor.Set_Right_Margin;
  4664.  
  4665.  
  4666.   { ----------------------------------------- }
  4667.   {                                           }
  4668.   { This procedure will bring up a dialog box }
  4669.   { that allows the user to set Right_Margin. }
  4670.   { Values must be < MaxLineLength and > 9.   }
  4671.   {                                           }
  4672.   { ----------------------------------------- }
  4673.  
  4674.  
  4675. VAR
  4676.  
  4677.   Code        : Integer;          { Used for Val conversion.      }
  4678.   Margin_Data : TRightMarginRec;  { Holds dialog results.         }
  4679.   Temp_Value  : Integer;          { Holds converted dialog value. }
  4680.  
  4681. begin
  4682.  
  4683.   with Margin_Data do
  4684.     begin
  4685.  
  4686.       Str (Right_Margin, Margin_Position);
  4687.  
  4688.       if EditorDialog (edRightMargin, @Margin_Position) <> Views.cmCancel then
  4689.         begin
  4690.           val (Margin_Position, Temp_Value, Code);
  4691.           if (Temp_Value <= MaxLineLength) and (Temp_Value > 9) then
  4692.             Right_Margin := Temp_Value;
  4693.         end;
  4694.  
  4695.     end;
  4696.  
  4697.  
  4698. end; { TEditor.Set_Right_Margin }
  4699.  
  4700.  
  4701. { RMSET - Stop. }
  4702.  
  4703.  
  4704.  
  4705. { -------------------------------------------------------------------------- }
  4706.  
  4707.  
  4708.  
  4709. procedure TEditor.SetSelect (NewStart, NewEnd : Word; CurStart : Boolean);
  4710.  
  4711. VAR
  4712.  
  4713.   Flags : Byte;
  4714.   P     : Word;
  4715.   L     : Word;
  4716.  
  4717. begin
  4718.  
  4719.   if CurStart then
  4720.     P := NewStart
  4721.   else
  4722.     P := NewEnd;
  4723.  
  4724.   Flags := ufUpdate;
  4725.  
  4726.   if (NewStart <> SelStart) or (NewEnd <> SelEnd) then
  4727.     if (NewStart <> NewEnd) or (SelStart <> SelEnd) then
  4728.       Flags := ufView;
  4729.  
  4730.   if P <> CurPtr then
  4731.   begin
  4732.  
  4733.     if P > CurPtr then
  4734.       begin
  4735.         L := P - CurPtr;
  4736.         Move (Buffer^[CurPtr + GapLen], Buffer^[CurPtr], L);
  4737.         Inc (CurPos.Y, CountLines (Buffer^[CurPtr], L));
  4738.         CurPtr := P;
  4739.       end
  4740.     else
  4741.       begin
  4742.         L := CurPtr - P;
  4743.         CurPtr := P;
  4744.         Dec (CurPos.Y, CountLines (Buffer^[CurPtr], L));
  4745.         Move (Buffer^[CurPtr], Buffer^[CurPtr + GapLen], L);
  4746.       end;
  4747.  
  4748.     DrawLine := CurPos.Y;
  4749.     DrawPtr := LineStart (P);
  4750.  
  4751.     CurPos.X := CharPos (DrawPtr, P);
  4752.  
  4753.     DelCount := 0;
  4754.     InsCount := 0;
  4755.  
  4756.     SetBufSize (BufLen);
  4757.  
  4758.   end;
  4759.  
  4760.   SelStart := NewStart;
  4761.   SelEnd := NewEnd;
  4762.  
  4763.   Update (Flags);
  4764.  
  4765.  
  4766. end; { TEditor.Select }
  4767.  
  4768.  
  4769.  
  4770. { -------------------------------------------------------------------------- }
  4771.  
  4772.  
  4773.  
  4774. procedure TEditor.SetState (AState : Word; Enable : Boolean);
  4775.  
  4776. begin
  4777.  
  4778.   TView.SetState (AState, Enable);
  4779.  
  4780.   case AState of
  4781.  
  4782.     Views.sfActive: begin
  4783.                       if HScrollBar <> nil then
  4784.                         HScrollBar^.SetState (Views.sfVisible, Enable);
  4785.                       if VScrollBar <> nil then
  4786.                         VScrollBar^.SetState (Views.sfVisible, Enable);
  4787.                       if Indicator <> nil then
  4788.                         Indicator^.SetState (Views.sfVisible, Enable);
  4789.                       UpdateCommands;
  4790.                     end;
  4791.  
  4792.     Views.sfExposed: if Enable then Unlock;
  4793.  
  4794.   end;
  4795.  
  4796.  
  4797. end; { TEditor.SetState }
  4798.  
  4799.  
  4800.  
  4801. { -------------------------------------------------------------------------- }
  4802.  
  4803.  
  4804.  
  4805. { PRETAB - Start. }
  4806.  
  4807. procedure TEditor.Set_Tabs;
  4808.  
  4809.  
  4810.  
  4811.   { ----------------------------------------- }
  4812.   {                                           }
  4813.   { This procedure will bring up a dialog box }
  4814.   { that allows the user to set tab stops.    }
  4815.   {                                           }
  4816.   { ----------------------------------------- }
  4817.  
  4818.  
  4819. VAR
  4820.  
  4821.   Index    : Integer;      { Index into string array. }
  4822.   Tab_Data : TTabStopRec;  { Holds dialog results.    }
  4823.  
  4824. begin
  4825.  
  4826.   with Tab_Data do
  4827.     begin
  4828.  
  4829.  
  4830.  
  4831.       { --------------------------------------------- }
  4832.       {                                               }
  4833.       { Assign current Tab_Settings to Tab_String.    }
  4834.       { Bring up the tab dialog so user can set tabs. }
  4835.       {                                               }
  4836.       { --------------------------------------------- }
  4837.  
  4838.  
  4839.       Tab_String := Copy (Tab_Settings, 1, Tab_Stop_Length);
  4840.  
  4841.       if EditorDialog (edSetTabStops, @Tab_String) <> Views.cmCancel then
  4842.         begin
  4843.  
  4844.  
  4845.  
  4846.           { --------------------------------------------------------------- }
  4847.           {                                                                 }
  4848.           { If Tab_String comes back as empty then set Tab_Settings to nil. }
  4849.           { Otherwise, find the last character in Tab_String that is not    }
  4850.           { a space and copy Tab_String into Tab_Settings up to that spot.  }
  4851.           {                                                                 }
  4852.           { --------------------------------------------------------------- }
  4853.  
  4854.  
  4855.           if Length (Tab_String) = 0 then
  4856.             begin
  4857.               FillChar (Tab_Settings, SizeOf (Tab_Settings), #0);
  4858.               Tab_Settings[0] := #0;
  4859.               Exit;
  4860.             end
  4861.           else
  4862.             begin
  4863.               Index := Length (Tab_String);
  4864.               while Tab_String[Index] <= #32 do
  4865.                 Dec (Index);
  4866.               Tab_Settings := Copy (Tab_String, 1, Index);
  4867.             end;
  4868.  
  4869.         end;
  4870.  
  4871.   end;
  4872.  
  4873.  
  4874. end; { TEditor.Set_Tabs }
  4875.  
  4876. { PRETAB - Stop. }
  4877.  
  4878.  
  4879.  
  4880. { -------------------------------------------------------------------------- }
  4881.  
  4882.  
  4883.  
  4884. procedure TEditor.StartSelect;
  4885.  
  4886. begin
  4887.  
  4888.   HideSelect;
  4889.   Selecting := True;
  4890.  
  4891.  
  4892. end; { TEditor.StartSelect }
  4893.  
  4894.  
  4895.  
  4896. { -------------------------------------------------------------------------- }
  4897.  
  4898.  
  4899.  
  4900. procedure TEditor.Store (var S : Objects.TStream);
  4901.  
  4902. begin
  4903.  
  4904.   TView.Store (S);
  4905.  
  4906.   PutPeerViewPtr (S, HScrollBar);
  4907.   PutPeerViewPtr (S, VScrollBar);
  4908.   PutPeerViewPtr (S, Indicator);
  4909.   S.Write (BufSize, SizeOf (Word));
  4910.  
  4911.  
  4912.   { STORE - Start. }
  4913.  
  4914.   { S.Write (Canundo, SizeOf (Boolean)); }
  4915.  
  4916.   { STORE - Stop. } {This item caused load/store bug. }
  4917.  
  4918.  
  4919.   { STATS  - Start. }
  4920.   { JLINE  - Start. }
  4921.   { MARK   - Start. }
  4922.   { RMSET  - Start. }
  4923.   { PRETAB - Start. }
  4924.   { WRAP   - Start. }
  4925.  
  4926.   S.Write (AutoIndent,   SizeOf (AutoIndent));
  4927.   S.Write (Line_Number,  SizeOf (Line_Number));
  4928.   S.Write (Place_Marker, SizeOf (Place_Marker));
  4929.   S.Write (Right_Margin, SizeOf (Right_Margin));
  4930.   S.Write (Tab_Settings, SizeOf (Tab_Settings));
  4931.   S.Write (Word_Wrap,    SizeOf (Word_Wrap));
  4932.  
  4933.   { WRAP   - Stop. }
  4934.   { PRETAB - Stop. }
  4935.   { RMSET  - Stop. }
  4936.   { MARK   - Stop. }
  4937.   { JLINE  - Stop. }
  4938.   { STATS  - Stop. } { Added these to allow load/store operations. }
  4939.  
  4940.  
  4941. end; { Editor.Store }
  4942.  
  4943.  
  4944.  
  4945. { -------------------------------------------------------------------------- }
  4946.  
  4947.  
  4948.  
  4949. { PRETAB - Start. }
  4950.  
  4951.  
  4952. procedure TEditor.Tab_Key (Select_Mode : Byte);
  4953.  
  4954.  
  4955.   { ------------------------------------------------------------------ }
  4956.   {                                                                    }
  4957.   { This function determines if we are in overstrike or insert mode,   }
  4958.   { and then moves the cursor if overstrike, or adds spaces if insert. }
  4959.   {                                                                    }
  4960.   { ------------------------------------------------------------------ }
  4961.  
  4962.  
  4963. VAR
  4964.  
  4965.   E        : Word;                   { End of current line.                }
  4966.   Index    : Integer;                { Loop counter.                       }
  4967.   Position : Integer;                { CurPos.X position.                  }
  4968.   S        : Word;                   { Start of current line.              }
  4969.   Spaces   : array [1..80] of Char;  { Array to hold spaces for insertion. }
  4970.  
  4971.  
  4972. begin
  4973.  
  4974.   E := LineEnd (CurPtr);
  4975.   S := LineStart (CurPtr);
  4976.  
  4977.  
  4978.  
  4979.   { -------------------------------------------- }
  4980.   {                                              }
  4981.   { Find the current horizontal cursor position. }
  4982.   { Now loop through the Tab_Settings string and }
  4983.   { find the next available tab stop.            }
  4984.   {                                              }
  4985.   { -------------------------------------------- }
  4986.  
  4987.  
  4988.   Position := CurPos.X + 1;
  4989.  
  4990.   repeat
  4991.     Inc (Position);
  4992.   until (Tab_Settings[Position] <> #32) or (Position >= Ord (Tab_Settings[0]));
  4993.  
  4994.   E := CurPos.X;
  4995.   Index := 1;
  4996.  
  4997.  
  4998.  
  4999.   { ---------------------------------------------------- }
  5000.   {                                                      }
  5001.   { Now we enter a loop to go to the next tab position.  }
  5002.   { If we are in overwrite mode, we just move the cursor }
  5003.   { through the text to the next tab stop.  If we are in }
  5004.   { insert mode, we add spaces to the Spaces array for   }
  5005.   { the number of times we loop.                         }
  5006.   {                                                      }
  5007.   { ---------------------------------------------------- }
  5008.  
  5009.  
  5010.   while Index < Position - E do
  5011.     begin
  5012.  
  5013.       if Overwrite then
  5014.         begin
  5015.           if (Position > LineEnd (CurPtr) - LineStart (CurPtr))
  5016.               or (Position > Ord (Tab_Settings[0])) then
  5017.             begin
  5018.               SetCurPtr (LineStart (LineMove (CurPtr, 1)), Select_Mode);
  5019.               Exit;
  5020.             end
  5021.           else
  5022.             if CurPtr < BufLen then
  5023.               SetCurPtr (NextChar (CurPtr), Select_Mode);
  5024.         end
  5025.       else
  5026.         begin
  5027.           if (Position > Right_Margin) or (Position > Ord (Tab_Settings[0])) then
  5028.             begin
  5029.               SetCurPtr (LineStart (LineMove (CurPtr, 1)), Select_Mode);
  5030.               Exit;
  5031.             end
  5032.           else
  5033.             Spaces[Index] := #32;
  5034.         end;
  5035.  
  5036.       Inc (Index);
  5037.  
  5038.   end;
  5039.  
  5040.  
  5041.  
  5042.   { -------------------------------------------------------------------- }
  5043.   {                                                                      }
  5044.   { If we are insert mode, we insert spaces to the next tab stop.        }
  5045.   { When we're all done, the cursor will be sitting on the new tab stop. }
  5046.   {                                                                      }
  5047.   { -------------------------------------------------------------------- }
  5048.  
  5049.  
  5050.   if not OverWrite then
  5051.     InsertText (@Spaces, Index - 1, False);
  5052.  
  5053.  
  5054. end; { TEditor.Tab_Key }
  5055.  
  5056. { PRETAB - Stop. }
  5057.  
  5058.  
  5059.  
  5060. { -------------------------------------------------------------------------- }
  5061.  
  5062.  
  5063.  
  5064. procedure TEditor.ToggleInsMode;
  5065.  
  5066. begin
  5067.  
  5068.   Overwrite := not Overwrite;
  5069.   SetState (sfCursorIns, not GetState (sfCursorIns));
  5070.  
  5071.  
  5072. end; { TEditor.ToggleInsMode }
  5073.  
  5074.  
  5075.  
  5076. { -------------------------------------------------------------------------- }
  5077.  
  5078.  
  5079.  
  5080. procedure TEditor.TrackCursor (Center : Boolean);
  5081.  
  5082. begin
  5083.  
  5084.   if Center then
  5085.     ScrollTo (CurPos.X - Size.X + 1, CurPos.Y - Size.Y div 2)
  5086.   else
  5087.     ScrollTo (Max (CurPos.X - Size.X + 1, Min (Delta.X, CurPos.X)),
  5088.               Max (CurPos.Y - Size.Y + 1, Min (Delta.Y, CurPos.Y)));
  5089.  
  5090.  
  5091. end; { TEditor.TrackCursor }
  5092.  
  5093.  
  5094.  
  5095. { -------------------------------------------------------------------------- }
  5096.  
  5097.  
  5098.  
  5099. procedure TEditor.Undo;
  5100.  
  5101. VAR
  5102.  
  5103.   Length : Word;
  5104.  
  5105. begin
  5106.  
  5107.   if (DelCount <> 0) or (InsCount <> 0) then
  5108.   begin
  5109.  
  5110.     { MARK - Start. }
  5111.  
  5112.     Update_Place_Markers (DelCount, 0, CurPtr, CurPtr + DelCount);
  5113.  
  5114.     { MARK - Stop. } { Update Place_Marker array if we undelete text. }
  5115.  
  5116.     SelStart := CurPtr - InsCount;
  5117.     SelEnd := CurPtr;
  5118.     Length := DelCount;
  5119.     DelCount := 0;
  5120.     InsCount := 0;
  5121.     InsertBuffer (Buffer, CurPtr + GapLen - Length, Length, False, True);
  5122.  
  5123.   end;
  5124.  
  5125.  
  5126. end; { TEditor.Undo }
  5127.  
  5128.  
  5129.  
  5130. { -------------------------------------------------------------------------- }
  5131.  
  5132.  
  5133.  
  5134. procedure TEditor.Unlock;
  5135.  
  5136. begin
  5137.  
  5138.   if LockCount > 0 then
  5139.   begin
  5140.     Dec (LockCount);
  5141.     if LockCount = 0 then
  5142.       DoUpdate;
  5143.   end;
  5144.  
  5145.  
  5146. end; { TEditor.Unlock }
  5147.  
  5148.  
  5149.  
  5150. { -------------------------------------------------------------------------- }
  5151.  
  5152.  
  5153.  
  5154. procedure TEditor.Update (AFlags : Byte);
  5155.  
  5156. begin
  5157.  
  5158.   UpdateFlags := UpdateFlags or AFlags;
  5159.  
  5160.   if LockCount = 0 then
  5161.     DoUpdate;
  5162.  
  5163.  
  5164. end; { TEditor.Update }
  5165.  
  5166.  
  5167.  
  5168. { -------------------------------------------------------------------------- }
  5169.  
  5170.  
  5171.  
  5172. procedure TEditor.UpdateCommands;
  5173.  
  5174. begin
  5175.  
  5176.   SetCmdState (cmUndo, (DelCount <> 0) or (InsCount <> 0));
  5177.  
  5178.   if not IsClipboard then
  5179.     begin
  5180.       SetCmdState (cmCut, HasSelection);
  5181.       SetCmdState (cmCopy, HasSelection);
  5182.       SetCmdState (cmPaste, (Clipboard <> nil) and (Clipboard^.HasSelection));
  5183.     end;
  5184.  
  5185.   SetCmdState (cmClear, HasSelection);
  5186.   SetCmdState (cmFind, True);
  5187.   SetCmdState (cmReplace, True);
  5188.   SetCmdState (cmSearchAgain, True);
  5189.  
  5190.  
  5191. end; { TEditor.UpdateCommands }
  5192.  
  5193.  
  5194.  
  5195. { -------------------------------------------------------------------------- }
  5196.  
  5197.  
  5198.  
  5199. { MARK - Start. }
  5200.  
  5201. procedure TEditor.Update_Place_Markers (AddCount : Word; KillCount : Word;
  5202.                                         StartPtr : Word;    EndPtr : Word);
  5203.  
  5204.  
  5205.   { -------------------------------------------------------- }
  5206.   {                                                          }
  5207.   { This procedure updates the position of the place markers }
  5208.   { as the user inserts and deletes text in the document.    }
  5209.   {                                                          }
  5210.   { -------------------------------------------------------- }
  5211.  
  5212.  
  5213. VAR
  5214.  
  5215.   Element : Byte;     { Place_Marker array element to traverse array with. }
  5216.  
  5217.  
  5218. begin
  5219.  
  5220.   for Element := 1 to 10 do
  5221.     begin
  5222.       if AddCount > 0 then
  5223.         begin
  5224.           if (Place_Marker[Element] >= Curptr)
  5225.               and (Place_Marker[Element] <> 0) then
  5226.             Place_Marker[Element] := Place_Marker[Element] + AddCount;
  5227.         end
  5228.       else
  5229.         begin
  5230.           if Place_Marker[Element] >= StartPtr then
  5231.             begin
  5232.               if (Place_Marker[Element] >= StartPtr) and
  5233.                  (Place_Marker[Element] < EndPtr) then
  5234.                 Place_marker[Element] := 0
  5235.               else
  5236.                 begin
  5237.                   if integer (Place_Marker[Element]) - integer (KillCount) > 0 then
  5238.                     Place_Marker[Element] := Place_Marker[Element] - KillCount
  5239.                   else
  5240.                     Place_Marker[Element] := 0;
  5241.                 end;
  5242.             end;
  5243.         end;
  5244.     end;
  5245.  
  5246.   { WRAP - Start. }
  5247.  
  5248.   if AddCount > 0 then
  5249.     BlankLine := BlankLine + AddCount
  5250.   else
  5251.     begin
  5252.       if integer (BlankLine) - Integer (KillCount) > 0 then
  5253.         BlankLine := BlankLine - KillCount
  5254.       else
  5255.         BlankLine := 0;
  5256.     end;
  5257.  
  5258.   { WRAP - Stop. }
  5259.  
  5260.  
  5261. end; { TEditor.Update_Place_Markers }
  5262.  
  5263. {MARK - Stop. }
  5264.  
  5265.  
  5266.  
  5267. { -------------------------------------------------------------------------- }
  5268.  
  5269.  
  5270.  
  5271. function TEditor.Valid (Command : Word) : Boolean;
  5272.  
  5273. begin
  5274.  
  5275.   Valid := IsValid;
  5276.  
  5277.  
  5278. end; { TEditor.Valid }
  5279.  
  5280.  
  5281.  
  5282. { -------------------------------------------------------------------------- }
  5283.  
  5284.  
  5285.  
  5286.          { ----------------------------------------------- }
  5287.          {                                                 }
  5288.          { The following methods are for the TMEMO object. }
  5289.          {                                                 }
  5290.          { ----------------------------------------------- }
  5291.  
  5292.  
  5293.  
  5294. constructor TMemo.Load (var S : Objects.TStream);
  5295.  
  5296. VAR
  5297.  
  5298.   Length : Word;
  5299.  
  5300. begin
  5301.  
  5302.   TEditor.Load (S);
  5303.   S.Read (Length, SizeOf (Word));
  5304.  
  5305.   if IsValid then
  5306.     begin
  5307.       S.Read (Buffer^[BufSize - Length], Length);
  5308.       SetBufLen (Length);
  5309.     end
  5310.   else
  5311.     S.Seek (S.GetPos + Length);
  5312.  
  5313.  
  5314. end; { TMemo.Load }
  5315.  
  5316.  
  5317.  
  5318. { -------------------------------------------------------------------------- }
  5319.  
  5320.  
  5321.  
  5322. function TMemo.DataSize : Word;
  5323.  
  5324. begin
  5325.  
  5326.   DataSize := BufSize + SizeOf (Word);
  5327.  
  5328.  
  5329. end; { TMemo.DataSize }
  5330.  
  5331.  
  5332.  
  5333. { -------------------------------------------------------------------------- }
  5334.  
  5335.  
  5336.  
  5337. procedure TMemo.GetData (var Rec);
  5338.  
  5339. VAR
  5340.  
  5341.   Data : TMemoData absolute Rec;
  5342.  
  5343. begin
  5344.  
  5345.   Data.Length := BufLen;
  5346.   Move (Buffer^, Data.Buffer, CurPtr);
  5347.   Move (Buffer^[CurPtr + GapLen], Data.Buffer[CurPtr], BufLen - CurPtr);
  5348.   FillChar (Data.Buffer[BufLen], BufSize - BufLen, 0);
  5349.  
  5350.  
  5351. end; { TMemo.GetData }
  5352.  
  5353.  
  5354.  
  5355. { -------------------------------------------------------------------------- }
  5356.  
  5357.  
  5358.  
  5359. function TMemo.GetPalette : Views.PPalette;
  5360.  
  5361. CONST
  5362.  
  5363.   P : String[Length (CMemo)] = CMemo;
  5364.  
  5365. begin
  5366.  
  5367.   GetPalette := @P;
  5368.  
  5369.  
  5370. end; { TMemo.GetPalette }
  5371.  
  5372.  
  5373.  
  5374. { -------------------------------------------------------------------------- }
  5375.  
  5376.  
  5377.  
  5378. procedure TMemo.HandleEvent (var Event : Drivers.TEvent);
  5379.  
  5380. begin
  5381.  
  5382.   if (Event.What <> Drivers.evKeyDown) or (Event.KeyCode <> Drivers.kbTab) then
  5383.     TEditor.HandleEvent (Event);
  5384.  
  5385.  
  5386. end; { TMemo.HandleEvent }
  5387.  
  5388.  
  5389.  
  5390. { -------------------------------------------------------------------------- }
  5391.  
  5392.  
  5393.  
  5394. procedure TMemo.SetData (var Rec);
  5395.  
  5396. VAR
  5397.  
  5398.   Data : TMemoData absolute Rec;
  5399.  
  5400. begin
  5401.  
  5402.   Move (Data.Buffer, Buffer^[BufSize - Data.Length], Data.Length);
  5403.   SetBufLen (Data.Length);
  5404.  
  5405.  
  5406. end; { TMemo.SetData }
  5407.  
  5408.  
  5409.  
  5410. { -------------------------------------------------------------------------- }
  5411.  
  5412.  
  5413.  
  5414. procedure TMemo.Store (var S : Objects.TStream);
  5415.  
  5416. begin
  5417.  
  5418.   TEditor.Store (S);
  5419.   S.Write (BufLen, SizeOf (Word));
  5420.   S.Write (Buffer^, CurPtr);
  5421.   S.Write (Buffer^[CurPtr + GapLen], BufLen - CurPtr);
  5422.  
  5423.  
  5424. end; { TMemo.Store }
  5425.  
  5426.  
  5427.  
  5428. { -------------------------------------------------------------------------- }
  5429.  
  5430.  
  5431.  
  5432.          { ----------------------------------------------------- }
  5433.          {                                                       }
  5434.          { The following methods are for the TFILEEDITOR object. }
  5435.          {                                                       }
  5436.          { ----------------------------------------------------- }
  5437.  
  5438.  
  5439.  
  5440. constructor TFileEditor.Init (var Bounds : TRect;
  5441.                               AHScrollBar, AVScrollBar : PScrollBar;
  5442.                               AIndicator : PIndicator;
  5443.                               AFileName  : FNameStr);
  5444.  
  5445. begin
  5446.  
  5447.   TEditor.Init (Bounds, AHScrollBar, AVScrollBar, AIndicator, 0);
  5448.  
  5449.   if AFileName <> '' then
  5450.   begin
  5451.  
  5452.     FileName := FExpand (AFileName);
  5453.     if IsValid then
  5454.       IsValid := LoadFile;
  5455.  
  5456.   end;
  5457.  
  5458.  
  5459. end; { TFileEditor.Init }
  5460.  
  5461.  
  5462.  
  5463. { -------------------------------------------------------------------------- }
  5464.  
  5465.  
  5466.  
  5467. constructor TFileEditor.Load (var S : Objects.TStream);
  5468.  
  5469. VAR
  5470.  
  5471.   SStart : Word;
  5472.   SEnd   : Word;
  5473.   Curs   : Word;
  5474.  
  5475. begin
  5476.  
  5477.   TEditor.Load (S);
  5478.  
  5479.   S.Read (FileName[0], SizeOf (Char));
  5480.   S.Read (Filename[1], Length (FileName));
  5481.  
  5482.   if IsValid then
  5483.     IsValid := LoadFile;
  5484.  
  5485.   S.Read (SStart, SizeOf (Word));
  5486.   S.Read (SEnd, SizeOf (Word));
  5487.   S.Read (Curs, SizeOf (Word));
  5488.  
  5489.   if IsValid and (SEnd <= BufLen) then
  5490.   begin
  5491.     SetSelect (SStart, SEnd, Curs = SStart);
  5492.     TrackCursor (True);
  5493.   end;
  5494.  
  5495.  
  5496. end; { TFileEditor.Load }
  5497.  
  5498.  
  5499.  
  5500. { -------------------------------------------------------------------------- }
  5501.  
  5502.  
  5503.  
  5504. procedure TFileEditor.DoneBuffer;
  5505.  
  5506. begin
  5507.  
  5508.   if Buffer <> nil then
  5509.     DisposeBuffer (Buffer);
  5510.  
  5511.  
  5512. end; { TFileEditor.DoneBuffer }
  5513.  
  5514.  
  5515.  
  5516. { -------------------------------------------------------------------------- }
  5517.  
  5518.  
  5519.  
  5520. procedure TFileEditor.HandleEvent (var Event : Drivers.TEvent);
  5521.  
  5522. begin
  5523.  
  5524.   TEditor.HandleEvent (Event);
  5525.  
  5526.   case Event.What of
  5527.     Drivers.evCommand:
  5528.       case Event.Command of
  5529.  
  5530.         cmSave   : Save;
  5531.         cmSaveAs : SaveAs;
  5532.  
  5533.         { SAVE - Start. }
  5534.  
  5535.         cmSaveDone : if Save then
  5536.                        begin
  5537.                          Event.What := Drivers.evCommand;
  5538.                          Event.command := Views.cmClose;
  5539.                          PutEvent (Event);
  5540.                         end;
  5541.  
  5542.         { SAVE - Stop. } { Added code to remove editor if ^KD or ^KX pressed. }
  5543.  
  5544.       else
  5545.         Exit;
  5546.       end;
  5547.   else
  5548.     Exit;
  5549.   end;
  5550.  
  5551.   ClearEvent (Event);
  5552.  
  5553.  
  5554. end; { TFileEditor.HandleEvent }
  5555.  
  5556.  
  5557.  
  5558. { -------------------------------------------------------------------------- }
  5559.  
  5560.  
  5561.  
  5562. procedure TFileEditor.InitBuffer;
  5563.  
  5564. begin
  5565.  
  5566.   NewBuffer (Pointer (Buffer));
  5567.  
  5568.   { LOAD  - Start. }
  5569.   { STORE - Start. }
  5570.  
  5571.   BufSize := 0;
  5572.  
  5573.   { STORE - Stop. }
  5574.   { LOAD  - Stop. }
  5575.  
  5576.  
  5577. end; { TFileEditor.InitBuffer }
  5578.  
  5579.  
  5580.  
  5581. { -------------------------------------------------------------------------- }
  5582.  
  5583.  
  5584.  
  5585. function TFileEditor.LoadFile : Boolean;
  5586.  
  5587. VAR
  5588.  
  5589.   Length : Word;
  5590.   FSize  : Longint;
  5591.   F      : File;
  5592.  
  5593. begin
  5594.  
  5595.   LoadFile := False;
  5596.   Length := 0;
  5597.   Assign (F, FileName);
  5598.   Reset (F, 1);
  5599.  
  5600.   if IOResult <> 0 then
  5601.     LoadFile := True
  5602.   else
  5603.     begin
  5604.  
  5605.       FSize := FileSize (F);
  5606.  
  5607.       if (FSize > $FFF0) or not SetBufSize (Word (FSize)) then
  5608.         EditorDialog (edOutOfMemory, nil)
  5609.       else
  5610.         begin
  5611.  
  5612.           BlockRead (F, Buffer^[BufSize - Word (FSize)], FSize);
  5613.  
  5614.           if IOResult <> 0 then
  5615.             EditorDialog (edReadError, @FileName)
  5616.           else
  5617.             begin
  5618.               LoadFile := True;
  5619.               Length := FSize;
  5620.             end;
  5621.  
  5622.         end;
  5623.  
  5624.         Close (F);
  5625.  
  5626.     end;
  5627.  
  5628.   SetBufLen (Length);
  5629.  
  5630.  
  5631. end; { TFileEditor.LoadFile }
  5632.  
  5633.  
  5634.  
  5635. { -------------------------------------------------------------------------- }
  5636.  
  5637.  
  5638.  
  5639. function TFileEditor.Save : Boolean;
  5640.  
  5641. begin
  5642.  
  5643.   if FileName = '' then
  5644.     Save := SaveAs
  5645.   else
  5646.     Save := SaveFile;
  5647.  
  5648.  
  5649. end; { TFileEditor.Save }
  5650.  
  5651.  
  5652.  
  5653. { -------------------------------------------------------------------------- }
  5654.  
  5655.  
  5656.  
  5657. function TFileEditor.SaveAs : Boolean;
  5658.  
  5659. begin
  5660.  
  5661.   SaveAs := False;
  5662.  
  5663.   if EditorDialog (edSaveAs, @FileName) <> Views.cmCancel then
  5664.   begin
  5665.  
  5666.     FileName := FExpand (FileName);
  5667.     Message (Owner, Drivers.evBroadcast, cmUpdateTitle, nil);
  5668.     SaveAs := SaveFile;
  5669.  
  5670.     if IsClipboard then
  5671.       FileName := '';
  5672.   end;
  5673.  
  5674.  
  5675. end; { TFileEditor.SaveAs }
  5676.  
  5677.  
  5678.  
  5679. { -------------------------------------------------------------------------- }
  5680.  
  5681.  
  5682.  
  5683. function TFileEditor.SaveFile : Boolean;
  5684.  
  5685. VAR
  5686.  
  5687.   F          : File;
  5688.   BackupName : Objects.FNameStr;
  5689.   D          : DOS.DirStr;
  5690.   N          : DOS.NameStr;
  5691.   E          : DOS.ExtStr;
  5692.  
  5693. begin
  5694.  
  5695.   SaveFile := False;
  5696.  
  5697.   if EditorFlags and efBackupFiles <> 0 then
  5698.   begin
  5699.     FSplit (FileName, D, N, E);
  5700.     BackupName := D + N + '.BAK';
  5701.     Assign (F, BackupName);
  5702.     Erase (F);
  5703.     Assign (F, FileName);
  5704.     Rename (F, BackupName);
  5705.     InOutRes := 0;
  5706.   end;
  5707.  
  5708.   Assign (F, FileName);
  5709.   Rewrite (F, 1);
  5710.  
  5711.   if IOResult <> 0 then
  5712.     EditorDialog (edCreateError, @FileName)
  5713.   else
  5714.     begin
  5715.  
  5716.       BlockWrite (F, Buffer^, CurPtr);
  5717.       BlockWrite (F, Buffer^[CurPtr + GapLen], BufLen - CurPtr);
  5718.  
  5719.       if IOResult <> 0 then
  5720.         EditorDialog (edWriteError, @FileName)
  5721.       else
  5722.         begin
  5723.           Modified := False;
  5724.           Update (ufUpdate);
  5725.           SaveFile := True;
  5726.         end;
  5727.         Close (F);
  5728.       end;
  5729.  
  5730.  
  5731. end; { TFileEditor.SaveFile }
  5732.  
  5733.  
  5734.  
  5735. { -------------------------------------------------------------------------- }
  5736.  
  5737.  
  5738.  
  5739. function TFileEditor.SetBufSize (NewSize : Word) : Boolean;
  5740.  
  5741. VAR
  5742.  
  5743.   N : Word;
  5744.  
  5745. begin
  5746.  
  5747.   SetBufSize := False;
  5748.   if NewSize > $F000 then
  5749.     NewSize := $FFF0
  5750.   else
  5751.     NewSize := (NewSize + $0FFF) and $F000;
  5752.  
  5753.   if NewSize <> BufSize then
  5754.   begin
  5755.  
  5756.     if NewSize > BufSize then
  5757.       if not SetBufferSize (Buffer, NewSize) then
  5758.         Exit;
  5759.  
  5760.     N := BufLen - CurPtr + DelCount;
  5761.     Move (Buffer^[BufSize - N], Buffer^[NewSize - N], N);
  5762.  
  5763.     if NewSize < BufSize then
  5764.       SetBufferSize (Buffer, NewSize);
  5765.  
  5766.     BufSize := NewSize;
  5767.     GapLen := BufSize - BufLen;
  5768.  
  5769.   end;
  5770.  
  5771.   SetBufSize := True;
  5772.  
  5773.  
  5774. end; { TFileEditor.SetBufSize }
  5775.  
  5776.  
  5777.  
  5778. { -------------------------------------------------------------------------- }
  5779.  
  5780.  
  5781.  
  5782. procedure TFileEditor.Store (var S : Objects.TStream);
  5783.  
  5784. begin
  5785.  
  5786.   TEditor.Store (S);
  5787.   S.Write (FileName, Length (FileName) + 1);
  5788.   S.Write (SelStart, SizeOf (Word) * 3);
  5789.  
  5790.  
  5791. end; { TFileEditor.Store }
  5792.  
  5793.  
  5794.  
  5795. { -------------------------------------------------------------------------- }
  5796.  
  5797.  
  5798.  
  5799. procedure TFileEditor.UpdateCommands;
  5800.  
  5801. begin
  5802.  
  5803.   TEditor.UpdateCommands;
  5804.  
  5805.   SetCmdState (cmSave, True);
  5806.   SetCmdState (cmSaveAs, True);
  5807.  
  5808.   { SAVE - Start. }
  5809.  
  5810.   SetCmdState (cmSaveDone, True);
  5811.  
  5812.   { SAVE - Stop. } { Added cmSaveDone toggle. }
  5813.  
  5814.  
  5815.  
  5816.   { -------------------------------------------------------------------- }
  5817.   {                                                                      }
  5818.   { The following SetCmdState calls are included to allow you to disable }
  5819.   { any custom menu options you design for the editor features.  I have  }
  5820.   { commented them out.  You pay a price in speed performance for EACH   }
  5821.   { option you uncomment.  Read the MENU section of NEWEDIT.DOC!         }
  5822.   {                                                                      }
  5823.   { -------------------------------------------------------------------- }
  5824.  
  5825.  
  5826.   { CENTER - Start. }
  5827.   { HOMEND - Start. }
  5828.   { INSLIN - Start. }
  5829.   { JLINE  - Start. }
  5830.   { MARK   - Start. }
  5831.   { PRETAB - Start. }
  5832.   { REFDOC - Start. }
  5833.   { REFORM - Start. }
  5834.   { RMSET  - Start. }
  5835.   { SCRLDN - Start. }
  5836.   { SCRLDN - Start. }
  5837.   { SELWRD - Start. }
  5838.   { WRAP   - Start. }
  5839.  
  5840.   { SetCmdState (cmCenterText, True);  }
  5841.   { SetCmdState (cmEndPage, True);     }
  5842.   { SetCmdState (cmHomePage, True);    }
  5843.   { SetCmdState (cmIndentMode, True);  }
  5844.   { SetCmdState (cmInsertLine, True);  }
  5845.   { SetCmdState (cmJumpLine, True);    }
  5846.   { SetCmdState (cmJumpMark0, True);   }
  5847.   { SetCmdState (cmJumpMark1, True);   }
  5848.   { SetCmdState (cmJumpMark2, True);   }
  5849.   { SetCmdState (cmJumpMark3, True);   }
  5850.   { SetCmdState (cmJumpMark4, True);   }
  5851.   { SetCmdState (cmJumpMark5, True);   }
  5852.   { SetCmdState (cmJumpMark6, True);   }
  5853.   { SetCmdState (cmJumpMark7, True);   }
  5854.   { SetCmdState (cmJumpMark8, True);   }
  5855.   { SetCmdState (cmJumpMark9, True);   }
  5856.   { SetCmdState (cmReformDoc, True);   }
  5857.   { SetCmdState (cmReformPara, True);  }
  5858.   { SetCmdState (cmRightMargin, True); }
  5859.   { SetCmdState (cmScrollDown, True);  }
  5860.   { SetCmdState (cmScrollUp, True);    }
  5861.   { SetCmdState (cmSelectWord, True);  }
  5862.   { SetCmdState (cmSetMark0, True);    }
  5863.   { SetCmdState (cmSetMark1, True);    }
  5864.   { SetCmdState (cmSetMark2, True);    }
  5865.   { SetCmdState (cmSetMark3, True);    }
  5866.   { SetCmdState (cmSetMark4, True);    }
  5867.   { SetCmdState (cmSetMark5, True);    }
  5868.   { SetCmdState (cmSetMark6, True);    }
  5869.   { SetCmdState (cmSetMark7, True);    }
  5870.   { SetCmdState (cmSetMark8, True);    }
  5871.   { SetCmdState (cmSetMark9, True);    }
  5872.   { SetCmdState (cmSetTabs, True);     }
  5873.   { SetCmdState (cmTabKey, True);      }
  5874.   { SetCmdState (cmWordWrap, True);    }
  5875.  
  5876.  
  5877.   { WRAP   - Stop. }
  5878.   { SELWRD - Stop. }
  5879.   { SCRLUP - Stop. }
  5880.   { SCRLDN - Stop. }
  5881.   { RMSET  - Stop. }
  5882.   { REFORM - Stop. }
  5883.   { REFDOC - Stop. }
  5884.   { PRETAB - Stop. }
  5885.   { MARK   - Stop. }
  5886.   { JLINE  - Stop. }
  5887.   { INSLIN - Stop. }
  5888.   { HOMEND - Stop. }
  5889.   { CENTER - Stop. } { This was required so these command constants may }
  5890.                      { be used in enabling and disabling menu options.  }
  5891.  
  5892.  
  5893. end; { TFileEditor.UpdateCommands }
  5894.  
  5895.  
  5896.  
  5897. { -------------------------------------------------------------------------- }
  5898.  
  5899.  
  5900.  
  5901. function TFileEditor.Valid (Command : Word) : Boolean;
  5902.  
  5903. VAR
  5904.  
  5905.   D : Integer;
  5906.  
  5907. begin
  5908.  
  5909.   if Command = Views.cmValid then
  5910.     Valid := IsValid
  5911.   else
  5912.     begin
  5913.  
  5914.       Valid := True;
  5915.  
  5916.       if Modified then
  5917.       begin
  5918.  
  5919.         if FileName = '' then
  5920.           D := edSaveUntitled
  5921.         else
  5922.           D := edSaveModify;
  5923.  
  5924.         case EditorDialog (D, @FileName) of
  5925.           Views.cmYes    : Valid := Save;
  5926.           Views.cmNo     : Modified := False;
  5927.           Views.cmCancel : Valid := False;
  5928.  
  5929.         end;
  5930.  
  5931.       end;
  5932.  
  5933.     end;
  5934.  
  5935.  
  5936. end; { TFileEditor.Valid }
  5937.  
  5938.  
  5939.  
  5940. { -------------------------------------------------------------------------- }
  5941.  
  5942.  
  5943.  
  5944.          { ----------------------------------------------------- }
  5945.          {                                                       }
  5946.          { The following methods are for the TEDITWINDOW object. }
  5947.          {                                                       }
  5948.          { ----------------------------------------------------- }
  5949.  
  5950.  
  5951.  
  5952. constructor TEditWindow.Init (var Bounds   : TRect;
  5953.                                   FileName : Objects.FNameStr;
  5954.                                   ANumber  : Integer);
  5955.  
  5956. VAR
  5957.  
  5958.   HScrollBar : Views.PScrollBar;
  5959.   VScrollBar : Views.PScrollBar;
  5960.   Indicator  : PIndicator;
  5961.   R          : TRect;
  5962.  
  5963. begin
  5964.  
  5965.   TWindow.Init (Bounds, '', ANumber);
  5966.   Options := Options or Views.ofTileable;
  5967.  
  5968.   R.Assign (18, Size.Y - 1, Size.X - 2, Size.Y);
  5969.   HScrollBar := New (Views.PScrollBar, Init (R));
  5970.   HScrollBar^.Hide;
  5971.   Insert (HScrollBar);
  5972.  
  5973.   R.Assign (Size.X - 1, 1, Size.X, Size.Y - 1);
  5974.   VScrollBar := New (Views.PScrollBar, Init (R));
  5975.   VScrollBar^.Hide;
  5976.   Insert (VScrollBar);
  5977.  
  5978.   R.Assign (2, Size.Y - 1, 16, Size.Y);
  5979.   Indicator := New (PIndicator, Init (R));
  5980.   Indicator^.Hide;
  5981.   Insert (Indicator);
  5982.  
  5983.   GetExtent (R);
  5984.   R.Grow (-1, -1);
  5985.   Editor := New (PFileEditor, Init (R, HScrollBar, VScrollBar, Indicator, FileName));
  5986.  
  5987.   Insert (Editor);
  5988.  
  5989.  
  5990. end; { TEditWindow.Init }
  5991.  
  5992.  
  5993.  
  5994. { -------------------------------------------------------------------------- }
  5995.  
  5996.  
  5997.  
  5998. constructor TEditWindow.Load (var S : Objects.TStream);
  5999.  
  6000. begin
  6001.  
  6002.   TWindow.Load (S);
  6003.   GetSubViewPtr (S, Editor);
  6004.  
  6005.  
  6006. end; { TEditWindow.Load }
  6007.  
  6008.  
  6009.  
  6010. { -------------------------------------------------------------------------- }
  6011.  
  6012.  
  6013.  
  6014. procedure TEditWindow.Close;
  6015.  
  6016. VAR
  6017.  
  6018.   Event : Drivers.TEvent;
  6019.  
  6020. begin
  6021.  
  6022.   if Editor^.IsClipboard then
  6023.     Hide
  6024.   else
  6025.     TWindow.Close;
  6026.  
  6027.  
  6028. end; { TEditWindow.Close }
  6029.  
  6030.  
  6031.  
  6032. { -------------------------------------------------------------------------- }
  6033.  
  6034.  
  6035.  
  6036. function TEditWindow.GetTitle (MaxSize : Integer) : Views.TTitleStr;
  6037.  
  6038. begin
  6039.  
  6040.   if Editor^.IsClipboard then
  6041.     GetTitle := 'Clipboard'
  6042.   else
  6043.     if Editor^.FileName = '' then
  6044.       GetTitle := 'Untitled'
  6045.     else
  6046.       GetTitle := Editor^.FileName;
  6047.  
  6048.  
  6049. end; { TEditWindow.GetTile }
  6050.  
  6051.  
  6052.  
  6053. { -------------------------------------------------------------------------- }
  6054.  
  6055.  
  6056.  
  6057. procedure TEditWindow.HandleEvent (var Event : Drivers.TEvent);
  6058.  
  6059. begin
  6060.  
  6061.   TWindow.HandleEvent (Event);
  6062.  
  6063.   if (Event.What = Drivers.evBroadcast) then
  6064.     { and (Event.Command = cmUpdateTitle) then }
  6065.  
  6066.  
  6067.  
  6068.     { STATS - Start. }
  6069.  
  6070.     { -------------------------------------------------------------------- }
  6071.     {                                                                      }
  6072.     { Changed if statement above so I could test for cmBlugeonStats.       }
  6073.     { Stats would not show up when loading a file until a key was pressed. }
  6074.     {                                                                      }
  6075.     { -------------------------------------------------------------------- }
  6076.  
  6077.  
  6078.     case Event.Command of
  6079.       cmUpdateTitle   : begin
  6080.                           Frame^.DrawView;
  6081.                           ClearEvent (Event);
  6082.                         end;
  6083.  
  6084.       cmBludgeonStats : begin
  6085.                           Editor^.Update (ufStats);
  6086.                           ClearEvent (Event);
  6087.                         end;
  6088.     end;
  6089.  
  6090.     { STATS - Stop. }
  6091.  
  6092.  
  6093. end; { TEditWindow.HandleEvent }
  6094.  
  6095.  
  6096.  
  6097. { -------------------------------------------------------------------------- }
  6098.  
  6099.  
  6100.  
  6101. procedure TEditWindow.Store (var S : Objects.TStream);
  6102.  
  6103. begin
  6104.  
  6105.   TWindow.Store (S);
  6106.   PutSubViewPtr (S, Editor);
  6107.  
  6108.  
  6109. end; { TEditWindow.Store }
  6110.  
  6111.  
  6112.  
  6113. { -------------------------------------------------------------------------- }
  6114.  
  6115.  
  6116.  
  6117. procedure RegisterEditors;
  6118.  
  6119. begin
  6120.  
  6121.   RegisterType (REditor);
  6122.   RegisterType (RMemo);
  6123.   RegisterType (RFileEditor);
  6124.   RegisterType (RIndicator);
  6125.   RegisterType (REditWindow);
  6126.  
  6127. end; { RegisterEditors }
  6128.  
  6129.  
  6130.  
  6131. { -------------------------------------------------------------------------- }
  6132.  
  6133.  
  6134.  
  6135. end. { Unit NewEdit }
  6136.